Minero
Loading...
Searching...
No Matches
json.hpp
Go to the documentation of this file.
1/*
2 __ _____ _____ _____
3 __| | __| | | | JSON for Modern C++
4| | |__ | | | | | | version 3.10.5
5|_____|_____|_____|_|___| https://github.com/nlohmann/json
6
7Licensed under the MIT License <http://opensource.org/licenses/MIT>.
8SPDX-License-Identifier: MIT
9Copyright (c) 2013-2022 Niels Lohmann <http://nlohmann.me>.
10
11Permission is hereby granted, free of charge, to any person obtaining a copy
12of this software and associated documentation files (the "Software"), to deal
13in the Software without restriction, including without limitation the rights
14to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
15copies of the Software, and to permit persons to whom the Software is
16furnished to do so, subject to the following conditions:
17
18The above copyright notice and this permission notice shall be included in all
19copies or substantial portions of the Software.
20
21THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
22IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
23FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
24AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
25LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
26OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
27SOFTWARE.
28*/
29
30/****************************************************************************\
31 * Note on documentation: The source files contain links to the online *
32 * documentation of the public API at https://json.nlohmann.me. This URL *
33 * contains the most recent documentation and should also be applicable to *
34 * previous versions; documentation for deprecated functions is not *
35 * removed, but marked deprecated. See "Generate documentation" section in *
36 * file docs/README.md. *
37\****************************************************************************/
38
39#ifndef INCLUDE_NLOHMANN_JSON_HPP_
40#define INCLUDE_NLOHMANN_JSON_HPP_
41
42#ifndef JSON_SKIP_LIBRARY_VERSION_CHECK
43 #if defined(NLOHMANN_JSON_VERSION_MAJOR) && defined(NLOHMANN_JSON_VERSION_MINOR) && defined(NLOHMANN_JSON_VERSION_PATCH)
44 #if NLOHMANN_JSON_VERSION_MAJOR != 3 || NLOHMANN_JSON_VERSION_MINOR != 10 || NLOHMANN_JSON_VERSION_PATCH != 5
45 #warning "Already included a different version of the library!"
46 #endif
47 #endif
48#endif
49
50#define NLOHMANN_JSON_VERSION_MAJOR 3 // NOLINT(modernize-macro-to-enum)
51#define NLOHMANN_JSON_VERSION_MINOR 10 // NOLINT(modernize-macro-to-enum)
52#define NLOHMANN_JSON_VERSION_PATCH 5 // NOLINT(modernize-macro-to-enum)
53
54#include <algorithm> // all_of, find, for_each
55#include <cstddef> // nullptr_t, ptrdiff_t, size_t
56#include <functional> // hash, less
57#include <initializer_list> // initializer_list
58#ifndef JSON_NO_IO
59 #include <iosfwd> // istream, ostream
60#endif // JSON_NO_IO
61#include <iterator> // random_access_iterator_tag
62#include <memory> // unique_ptr
63#include <numeric> // accumulate
64#include <string> // string, stoi, to_string
65#include <utility> // declval, forward, move, pair, swap
66#include <vector> // vector
67
68// #include <nlohmann/adl_serializer.hpp>
69
70
71#include <type_traits>
72#include <utility>
73
74// #include <nlohmann/detail/conversions/from_json.hpp>
75
76
77#include <algorithm> // transform
78#include <array> // array
79#include <forward_list> // forward_list
80#include <iterator> // inserter, front_inserter, end
81#include <map> // map
82#include <string> // string
83#include <tuple> // tuple, make_tuple
84#include <type_traits> // is_arithmetic, is_same, is_enum, underlying_type, is_convertible
85#include <unordered_map> // unordered_map
86#include <utility> // pair, declval
87#include <valarray> // valarray
88
89// #include <nlohmann/detail/exceptions.hpp>
90
91
92#include <cstddef> // nullptr_t
93#include <exception> // exception
94#include <stdexcept> // runtime_error
95#include <string> // to_string
96#include <vector> // vector
97
98// #include <nlohmann/detail/value_t.hpp>
99
100
101#include <array> // array
102#include <cstddef> // size_t
103#include <cstdint> // uint8_t
104#include <string> // string
105
106namespace nlohmann
107{
108namespace detail
109{
111// JSON type enumeration //
113
138enum class value_t : std::uint8_t
139{
140 null,
141 object,
142 array,
143 string,
144 boolean,
148 binary,
149 discarded
150};
151
165inline bool operator<(const value_t lhs, const value_t rhs) noexcept
166{
167 static constexpr std::array<std::uint8_t, 9> order = {{
168 0 /* null */, 3 /* object */, 4 /* array */, 5 /* string */,
169 1 /* boolean */, 2 /* integer */, 2 /* unsigned */, 2 /* float */,
170 6 /* binary */
171 }
172 };
173
174 const auto l_index = static_cast<std::size_t>(lhs);
175 const auto r_index = static_cast<std::size_t>(rhs);
176 return l_index < order.size() && r_index < order.size() && order[l_index] < order[r_index];
177}
178} // namespace detail
179} // namespace nlohmann
180
181// #include <nlohmann/detail/string_escape.hpp>
182
183
184// #include <nlohmann/detail/macro_scope.hpp>
185
186
187#include <utility> // declval, pair
188// #include <nlohmann/thirdparty/hedley/hedley.hpp>
189
190
191/* Hedley - https://nemequ.github.io/hedley
192 * Created by Evan Nemerson <evan@nemerson.com>
193 *
194 * To the extent possible under law, the author(s) have dedicated all
195 * copyright and related and neighboring rights to this software to
196 * the public domain worldwide. This software is distributed without
197 * any warranty.
198 *
199 * For details, see <http://creativecommons.org/publicdomain/zero/1.0/>.
200 * SPDX-License-Identifier: CC0-1.0
201 */
202
203#if !defined(JSON_HEDLEY_VERSION) || (JSON_HEDLEY_VERSION < 15)
204#if defined(JSON_HEDLEY_VERSION)
205 #undef JSON_HEDLEY_VERSION
206#endif
207#define JSON_HEDLEY_VERSION 15
208
209#if defined(JSON_HEDLEY_STRINGIFY_EX)
210 #undef JSON_HEDLEY_STRINGIFY_EX
211#endif
212#define JSON_HEDLEY_STRINGIFY_EX(x) #x
213
214#if defined(JSON_HEDLEY_STRINGIFY)
215 #undef JSON_HEDLEY_STRINGIFY
216#endif
217#define JSON_HEDLEY_STRINGIFY(x) JSON_HEDLEY_STRINGIFY_EX(x)
218
219#if defined(JSON_HEDLEY_CONCAT_EX)
220 #undef JSON_HEDLEY_CONCAT_EX
221#endif
222#define JSON_HEDLEY_CONCAT_EX(a,b) a##b
223
224#if defined(JSON_HEDLEY_CONCAT)
225 #undef JSON_HEDLEY_CONCAT
226#endif
227#define JSON_HEDLEY_CONCAT(a,b) JSON_HEDLEY_CONCAT_EX(a,b)
228
229#if defined(JSON_HEDLEY_CONCAT3_EX)
230 #undef JSON_HEDLEY_CONCAT3_EX
231#endif
232#define JSON_HEDLEY_CONCAT3_EX(a,b,c) a##b##c
233
234#if defined(JSON_HEDLEY_CONCAT3)
235 #undef JSON_HEDLEY_CONCAT3
236#endif
237#define JSON_HEDLEY_CONCAT3(a,b,c) JSON_HEDLEY_CONCAT3_EX(a,b,c)
238
239#if defined(JSON_HEDLEY_VERSION_ENCODE)
240 #undef JSON_HEDLEY_VERSION_ENCODE
241#endif
242#define JSON_HEDLEY_VERSION_ENCODE(major,minor,revision) (((major) * 1000000) + ((minor) * 1000) + (revision))
243
244#if defined(JSON_HEDLEY_VERSION_DECODE_MAJOR)
245 #undef JSON_HEDLEY_VERSION_DECODE_MAJOR
246#endif
247#define JSON_HEDLEY_VERSION_DECODE_MAJOR(version) ((version) / 1000000)
248
249#if defined(JSON_HEDLEY_VERSION_DECODE_MINOR)
250 #undef JSON_HEDLEY_VERSION_DECODE_MINOR
251#endif
252#define JSON_HEDLEY_VERSION_DECODE_MINOR(version) (((version) % 1000000) / 1000)
253
254#if defined(JSON_HEDLEY_VERSION_DECODE_REVISION)
255 #undef JSON_HEDLEY_VERSION_DECODE_REVISION
256#endif
257#define JSON_HEDLEY_VERSION_DECODE_REVISION(version) ((version) % 1000)
258
259#if defined(JSON_HEDLEY_GNUC_VERSION)
260 #undef JSON_HEDLEY_GNUC_VERSION
261#endif
262#if defined(__GNUC__) && defined(__GNUC_PATCHLEVEL__)
263 #define JSON_HEDLEY_GNUC_VERSION JSON_HEDLEY_VERSION_ENCODE(__GNUC__, __GNUC_MINOR__, __GNUC_PATCHLEVEL__)
264#elif defined(__GNUC__)
265 #define JSON_HEDLEY_GNUC_VERSION JSON_HEDLEY_VERSION_ENCODE(__GNUC__, __GNUC_MINOR__, 0)
266#endif
267
268#if defined(JSON_HEDLEY_GNUC_VERSION_CHECK)
269 #undef JSON_HEDLEY_GNUC_VERSION_CHECK
270#endif
271#if defined(JSON_HEDLEY_GNUC_VERSION)
272 #define JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_GNUC_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
273#else
274 #define JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch) (0)
275#endif
276
277#if defined(JSON_HEDLEY_MSVC_VERSION)
278 #undef JSON_HEDLEY_MSVC_VERSION
279#endif
280#if defined(_MSC_FULL_VER) && (_MSC_FULL_VER >= 140000000) && !defined(__ICL)
281 #define JSON_HEDLEY_MSVC_VERSION JSON_HEDLEY_VERSION_ENCODE(_MSC_FULL_VER / 10000000, (_MSC_FULL_VER % 10000000) / 100000, (_MSC_FULL_VER % 100000) / 100)
282#elif defined(_MSC_FULL_VER) && !defined(__ICL)
283 #define JSON_HEDLEY_MSVC_VERSION JSON_HEDLEY_VERSION_ENCODE(_MSC_FULL_VER / 1000000, (_MSC_FULL_VER % 1000000) / 10000, (_MSC_FULL_VER % 10000) / 10)
284#elif defined(_MSC_VER) && !defined(__ICL)
285 #define JSON_HEDLEY_MSVC_VERSION JSON_HEDLEY_VERSION_ENCODE(_MSC_VER / 100, _MSC_VER % 100, 0)
286#endif
287
288#if defined(JSON_HEDLEY_MSVC_VERSION_CHECK)
289 #undef JSON_HEDLEY_MSVC_VERSION_CHECK
290#endif
291#if !defined(JSON_HEDLEY_MSVC_VERSION)
292 #define JSON_HEDLEY_MSVC_VERSION_CHECK(major,minor,patch) (0)
293#elif defined(_MSC_VER) && (_MSC_VER >= 1400)
294 #define JSON_HEDLEY_MSVC_VERSION_CHECK(major,minor,patch) (_MSC_FULL_VER >= ((major * 10000000) + (minor * 100000) + (patch)))
295#elif defined(_MSC_VER) && (_MSC_VER >= 1200)
296 #define JSON_HEDLEY_MSVC_VERSION_CHECK(major,minor,patch) (_MSC_FULL_VER >= ((major * 1000000) + (minor * 10000) + (patch)))
297#else
298 #define JSON_HEDLEY_MSVC_VERSION_CHECK(major,minor,patch) (_MSC_VER >= ((major * 100) + (minor)))
299#endif
300
301#if defined(JSON_HEDLEY_INTEL_VERSION)
302 #undef JSON_HEDLEY_INTEL_VERSION
303#endif
304#if defined(__INTEL_COMPILER) && defined(__INTEL_COMPILER_UPDATE) && !defined(__ICL)
305 #define JSON_HEDLEY_INTEL_VERSION JSON_HEDLEY_VERSION_ENCODE(__INTEL_COMPILER / 100, __INTEL_COMPILER % 100, __INTEL_COMPILER_UPDATE)
306#elif defined(__INTEL_COMPILER) && !defined(__ICL)
307 #define JSON_HEDLEY_INTEL_VERSION JSON_HEDLEY_VERSION_ENCODE(__INTEL_COMPILER / 100, __INTEL_COMPILER % 100, 0)
308#endif
309
310#if defined(JSON_HEDLEY_INTEL_VERSION_CHECK)
311 #undef JSON_HEDLEY_INTEL_VERSION_CHECK
312#endif
313#if defined(JSON_HEDLEY_INTEL_VERSION)
314 #define JSON_HEDLEY_INTEL_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_INTEL_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
315#else
316 #define JSON_HEDLEY_INTEL_VERSION_CHECK(major,minor,patch) (0)
317#endif
318
319#if defined(JSON_HEDLEY_INTEL_CL_VERSION)
320 #undef JSON_HEDLEY_INTEL_CL_VERSION
321#endif
322#if defined(__INTEL_COMPILER) && defined(__INTEL_COMPILER_UPDATE) && defined(__ICL)
323 #define JSON_HEDLEY_INTEL_CL_VERSION JSON_HEDLEY_VERSION_ENCODE(__INTEL_COMPILER, __INTEL_COMPILER_UPDATE, 0)
324#endif
325
326#if defined(JSON_HEDLEY_INTEL_CL_VERSION_CHECK)
327 #undef JSON_HEDLEY_INTEL_CL_VERSION_CHECK
328#endif
329#if defined(JSON_HEDLEY_INTEL_CL_VERSION)
330 #define JSON_HEDLEY_INTEL_CL_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_INTEL_CL_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
331#else
332 #define JSON_HEDLEY_INTEL_CL_VERSION_CHECK(major,minor,patch) (0)
333#endif
334
335#if defined(JSON_HEDLEY_PGI_VERSION)
336 #undef JSON_HEDLEY_PGI_VERSION
337#endif
338#if defined(__PGI) && defined(__PGIC__) && defined(__PGIC_MINOR__) && defined(__PGIC_PATCHLEVEL__)
339 #define JSON_HEDLEY_PGI_VERSION JSON_HEDLEY_VERSION_ENCODE(__PGIC__, __PGIC_MINOR__, __PGIC_PATCHLEVEL__)
340#endif
341
342#if defined(JSON_HEDLEY_PGI_VERSION_CHECK)
343 #undef JSON_HEDLEY_PGI_VERSION_CHECK
344#endif
345#if defined(JSON_HEDLEY_PGI_VERSION)
346 #define JSON_HEDLEY_PGI_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_PGI_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
347#else
348 #define JSON_HEDLEY_PGI_VERSION_CHECK(major,minor,patch) (0)
349#endif
350
351#if defined(JSON_HEDLEY_SUNPRO_VERSION)
352 #undef JSON_HEDLEY_SUNPRO_VERSION
353#endif
354#if defined(__SUNPRO_C) && (__SUNPRO_C > 0x1000)
355 #define JSON_HEDLEY_SUNPRO_VERSION JSON_HEDLEY_VERSION_ENCODE((((__SUNPRO_C >> 16) & 0xf) * 10) + ((__SUNPRO_C >> 12) & 0xf), (((__SUNPRO_C >> 8) & 0xf) * 10) + ((__SUNPRO_C >> 4) & 0xf), (__SUNPRO_C & 0xf) * 10)
356#elif defined(__SUNPRO_C)
357 #define JSON_HEDLEY_SUNPRO_VERSION JSON_HEDLEY_VERSION_ENCODE((__SUNPRO_C >> 8) & 0xf, (__SUNPRO_C >> 4) & 0xf, (__SUNPRO_C) & 0xf)
358#elif defined(__SUNPRO_CC) && (__SUNPRO_CC > 0x1000)
359 #define JSON_HEDLEY_SUNPRO_VERSION JSON_HEDLEY_VERSION_ENCODE((((__SUNPRO_CC >> 16) & 0xf) * 10) + ((__SUNPRO_CC >> 12) & 0xf), (((__SUNPRO_CC >> 8) & 0xf) * 10) + ((__SUNPRO_CC >> 4) & 0xf), (__SUNPRO_CC & 0xf) * 10)
360#elif defined(__SUNPRO_CC)
361 #define JSON_HEDLEY_SUNPRO_VERSION JSON_HEDLEY_VERSION_ENCODE((__SUNPRO_CC >> 8) & 0xf, (__SUNPRO_CC >> 4) & 0xf, (__SUNPRO_CC) & 0xf)
362#endif
363
364#if defined(JSON_HEDLEY_SUNPRO_VERSION_CHECK)
365 #undef JSON_HEDLEY_SUNPRO_VERSION_CHECK
366#endif
367#if defined(JSON_HEDLEY_SUNPRO_VERSION)
368 #define JSON_HEDLEY_SUNPRO_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_SUNPRO_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
369#else
370 #define JSON_HEDLEY_SUNPRO_VERSION_CHECK(major,minor,patch) (0)
371#endif
372
373#if defined(JSON_HEDLEY_EMSCRIPTEN_VERSION)
374 #undef JSON_HEDLEY_EMSCRIPTEN_VERSION
375#endif
376#if defined(__EMSCRIPTEN__)
377 #define JSON_HEDLEY_EMSCRIPTEN_VERSION JSON_HEDLEY_VERSION_ENCODE(__EMSCRIPTEN_major__, __EMSCRIPTEN_minor__, __EMSCRIPTEN_tiny__)
378#endif
379
380#if defined(JSON_HEDLEY_EMSCRIPTEN_VERSION_CHECK)
381 #undef JSON_HEDLEY_EMSCRIPTEN_VERSION_CHECK
382#endif
383#if defined(JSON_HEDLEY_EMSCRIPTEN_VERSION)
384 #define JSON_HEDLEY_EMSCRIPTEN_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_EMSCRIPTEN_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
385#else
386 #define JSON_HEDLEY_EMSCRIPTEN_VERSION_CHECK(major,minor,patch) (0)
387#endif
388
389#if defined(JSON_HEDLEY_ARM_VERSION)
390 #undef JSON_HEDLEY_ARM_VERSION
391#endif
392#if defined(__CC_ARM) && defined(__ARMCOMPILER_VERSION)
393 #define JSON_HEDLEY_ARM_VERSION JSON_HEDLEY_VERSION_ENCODE(__ARMCOMPILER_VERSION / 1000000, (__ARMCOMPILER_VERSION % 1000000) / 10000, (__ARMCOMPILER_VERSION % 10000) / 100)
394#elif defined(__CC_ARM) && defined(__ARMCC_VERSION)
395 #define JSON_HEDLEY_ARM_VERSION JSON_HEDLEY_VERSION_ENCODE(__ARMCC_VERSION / 1000000, (__ARMCC_VERSION % 1000000) / 10000, (__ARMCC_VERSION % 10000) / 100)
396#endif
397
398#if defined(JSON_HEDLEY_ARM_VERSION_CHECK)
399 #undef JSON_HEDLEY_ARM_VERSION_CHECK
400#endif
401#if defined(JSON_HEDLEY_ARM_VERSION)
402 #define JSON_HEDLEY_ARM_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_ARM_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
403#else
404 #define JSON_HEDLEY_ARM_VERSION_CHECK(major,minor,patch) (0)
405#endif
406
407#if defined(JSON_HEDLEY_IBM_VERSION)
408 #undef JSON_HEDLEY_IBM_VERSION
409#endif
410#if defined(__ibmxl__)
411 #define JSON_HEDLEY_IBM_VERSION JSON_HEDLEY_VERSION_ENCODE(__ibmxl_version__, __ibmxl_release__, __ibmxl_modification__)
412#elif defined(__xlC__) && defined(__xlC_ver__)
413 #define JSON_HEDLEY_IBM_VERSION JSON_HEDLEY_VERSION_ENCODE(__xlC__ >> 8, __xlC__ & 0xff, (__xlC_ver__ >> 8) & 0xff)
414#elif defined(__xlC__)
415 #define JSON_HEDLEY_IBM_VERSION JSON_HEDLEY_VERSION_ENCODE(__xlC__ >> 8, __xlC__ & 0xff, 0)
416#endif
417
418#if defined(JSON_HEDLEY_IBM_VERSION_CHECK)
419 #undef JSON_HEDLEY_IBM_VERSION_CHECK
420#endif
421#if defined(JSON_HEDLEY_IBM_VERSION)
422 #define JSON_HEDLEY_IBM_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_IBM_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
423#else
424 #define JSON_HEDLEY_IBM_VERSION_CHECK(major,minor,patch) (0)
425#endif
426
427#if defined(JSON_HEDLEY_TI_VERSION)
428 #undef JSON_HEDLEY_TI_VERSION
429#endif
430#if \
431 defined(__TI_COMPILER_VERSION__) && \
432 ( \
433 defined(__TMS470__) || defined(__TI_ARM__) || \
434 defined(__MSP430__) || \
435 defined(__TMS320C2000__) \
436 )
437#if (__TI_COMPILER_VERSION__ >= 16000000)
438 #define JSON_HEDLEY_TI_VERSION JSON_HEDLEY_VERSION_ENCODE(__TI_COMPILER_VERSION__ / 1000000, (__TI_COMPILER_VERSION__ % 1000000) / 1000, (__TI_COMPILER_VERSION__ % 1000))
439#endif
440#endif
441
442#if defined(JSON_HEDLEY_TI_VERSION_CHECK)
443 #undef JSON_HEDLEY_TI_VERSION_CHECK
444#endif
445#if defined(JSON_HEDLEY_TI_VERSION)
446 #define JSON_HEDLEY_TI_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_TI_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
447#else
448 #define JSON_HEDLEY_TI_VERSION_CHECK(major,minor,patch) (0)
449#endif
450
451#if defined(JSON_HEDLEY_TI_CL2000_VERSION)
452 #undef JSON_HEDLEY_TI_CL2000_VERSION
453#endif
454#if defined(__TI_COMPILER_VERSION__) && defined(__TMS320C2000__)
455 #define JSON_HEDLEY_TI_CL2000_VERSION JSON_HEDLEY_VERSION_ENCODE(__TI_COMPILER_VERSION__ / 1000000, (__TI_COMPILER_VERSION__ % 1000000) / 1000, (__TI_COMPILER_VERSION__ % 1000))
456#endif
457
458#if defined(JSON_HEDLEY_TI_CL2000_VERSION_CHECK)
459 #undef JSON_HEDLEY_TI_CL2000_VERSION_CHECK
460#endif
461#if defined(JSON_HEDLEY_TI_CL2000_VERSION)
462 #define JSON_HEDLEY_TI_CL2000_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_TI_CL2000_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
463#else
464 #define JSON_HEDLEY_TI_CL2000_VERSION_CHECK(major,minor,patch) (0)
465#endif
466
467#if defined(JSON_HEDLEY_TI_CL430_VERSION)
468 #undef JSON_HEDLEY_TI_CL430_VERSION
469#endif
470#if defined(__TI_COMPILER_VERSION__) && defined(__MSP430__)
471 #define JSON_HEDLEY_TI_CL430_VERSION JSON_HEDLEY_VERSION_ENCODE(__TI_COMPILER_VERSION__ / 1000000, (__TI_COMPILER_VERSION__ % 1000000) / 1000, (__TI_COMPILER_VERSION__ % 1000))
472#endif
473
474#if defined(JSON_HEDLEY_TI_CL430_VERSION_CHECK)
475 #undef JSON_HEDLEY_TI_CL430_VERSION_CHECK
476#endif
477#if defined(JSON_HEDLEY_TI_CL430_VERSION)
478 #define JSON_HEDLEY_TI_CL430_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_TI_CL430_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
479#else
480 #define JSON_HEDLEY_TI_CL430_VERSION_CHECK(major,minor,patch) (0)
481#endif
482
483#if defined(JSON_HEDLEY_TI_ARMCL_VERSION)
484 #undef JSON_HEDLEY_TI_ARMCL_VERSION
485#endif
486#if defined(__TI_COMPILER_VERSION__) && (defined(__TMS470__) || defined(__TI_ARM__))
487 #define JSON_HEDLEY_TI_ARMCL_VERSION JSON_HEDLEY_VERSION_ENCODE(__TI_COMPILER_VERSION__ / 1000000, (__TI_COMPILER_VERSION__ % 1000000) / 1000, (__TI_COMPILER_VERSION__ % 1000))
488#endif
489
490#if defined(JSON_HEDLEY_TI_ARMCL_VERSION_CHECK)
491 #undef JSON_HEDLEY_TI_ARMCL_VERSION_CHECK
492#endif
493#if defined(JSON_HEDLEY_TI_ARMCL_VERSION)
494 #define JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_TI_ARMCL_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
495#else
496 #define JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(major,minor,patch) (0)
497#endif
498
499#if defined(JSON_HEDLEY_TI_CL6X_VERSION)
500 #undef JSON_HEDLEY_TI_CL6X_VERSION
501#endif
502#if defined(__TI_COMPILER_VERSION__) && defined(__TMS320C6X__)
503 #define JSON_HEDLEY_TI_CL6X_VERSION JSON_HEDLEY_VERSION_ENCODE(__TI_COMPILER_VERSION__ / 1000000, (__TI_COMPILER_VERSION__ % 1000000) / 1000, (__TI_COMPILER_VERSION__ % 1000))
504#endif
505
506#if defined(JSON_HEDLEY_TI_CL6X_VERSION_CHECK)
507 #undef JSON_HEDLEY_TI_CL6X_VERSION_CHECK
508#endif
509#if defined(JSON_HEDLEY_TI_CL6X_VERSION)
510 #define JSON_HEDLEY_TI_CL6X_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_TI_CL6X_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
511#else
512 #define JSON_HEDLEY_TI_CL6X_VERSION_CHECK(major,minor,patch) (0)
513#endif
514
515#if defined(JSON_HEDLEY_TI_CL7X_VERSION)
516 #undef JSON_HEDLEY_TI_CL7X_VERSION
517#endif
518#if defined(__TI_COMPILER_VERSION__) && defined(__C7000__)
519 #define JSON_HEDLEY_TI_CL7X_VERSION JSON_HEDLEY_VERSION_ENCODE(__TI_COMPILER_VERSION__ / 1000000, (__TI_COMPILER_VERSION__ % 1000000) / 1000, (__TI_COMPILER_VERSION__ % 1000))
520#endif
521
522#if defined(JSON_HEDLEY_TI_CL7X_VERSION_CHECK)
523 #undef JSON_HEDLEY_TI_CL7X_VERSION_CHECK
524#endif
525#if defined(JSON_HEDLEY_TI_CL7X_VERSION)
526 #define JSON_HEDLEY_TI_CL7X_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_TI_CL7X_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
527#else
528 #define JSON_HEDLEY_TI_CL7X_VERSION_CHECK(major,minor,patch) (0)
529#endif
530
531#if defined(JSON_HEDLEY_TI_CLPRU_VERSION)
532 #undef JSON_HEDLEY_TI_CLPRU_VERSION
533#endif
534#if defined(__TI_COMPILER_VERSION__) && defined(__PRU__)
535 #define JSON_HEDLEY_TI_CLPRU_VERSION JSON_HEDLEY_VERSION_ENCODE(__TI_COMPILER_VERSION__ / 1000000, (__TI_COMPILER_VERSION__ % 1000000) / 1000, (__TI_COMPILER_VERSION__ % 1000))
536#endif
537
538#if defined(JSON_HEDLEY_TI_CLPRU_VERSION_CHECK)
539 #undef JSON_HEDLEY_TI_CLPRU_VERSION_CHECK
540#endif
541#if defined(JSON_HEDLEY_TI_CLPRU_VERSION)
542 #define JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_TI_CLPRU_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
543#else
544 #define JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(major,minor,patch) (0)
545#endif
546
547#if defined(JSON_HEDLEY_CRAY_VERSION)
548 #undef JSON_HEDLEY_CRAY_VERSION
549#endif
550#if defined(_CRAYC)
551 #if defined(_RELEASE_PATCHLEVEL)
552 #define JSON_HEDLEY_CRAY_VERSION JSON_HEDLEY_VERSION_ENCODE(_RELEASE_MAJOR, _RELEASE_MINOR, _RELEASE_PATCHLEVEL)
553 #else
554 #define JSON_HEDLEY_CRAY_VERSION JSON_HEDLEY_VERSION_ENCODE(_RELEASE_MAJOR, _RELEASE_MINOR, 0)
555 #endif
556#endif
557
558#if defined(JSON_HEDLEY_CRAY_VERSION_CHECK)
559 #undef JSON_HEDLEY_CRAY_VERSION_CHECK
560#endif
561#if defined(JSON_HEDLEY_CRAY_VERSION)
562 #define JSON_HEDLEY_CRAY_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_CRAY_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
563#else
564 #define JSON_HEDLEY_CRAY_VERSION_CHECK(major,minor,patch) (0)
565#endif
566
567#if defined(JSON_HEDLEY_IAR_VERSION)
568 #undef JSON_HEDLEY_IAR_VERSION
569#endif
570#if defined(__IAR_SYSTEMS_ICC__)
571 #if __VER__ > 1000
572 #define JSON_HEDLEY_IAR_VERSION JSON_HEDLEY_VERSION_ENCODE((__VER__ / 1000000), ((__VER__ / 1000) % 1000), (__VER__ % 1000))
573 #else
574 #define JSON_HEDLEY_IAR_VERSION JSON_HEDLEY_VERSION_ENCODE(__VER__ / 100, __VER__ % 100, 0)
575 #endif
576#endif
577
578#if defined(JSON_HEDLEY_IAR_VERSION_CHECK)
579 #undef JSON_HEDLEY_IAR_VERSION_CHECK
580#endif
581#if defined(JSON_HEDLEY_IAR_VERSION)
582 #define JSON_HEDLEY_IAR_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_IAR_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
583#else
584 #define JSON_HEDLEY_IAR_VERSION_CHECK(major,minor,patch) (0)
585#endif
586
587#if defined(JSON_HEDLEY_TINYC_VERSION)
588 #undef JSON_HEDLEY_TINYC_VERSION
589#endif
590#if defined(__TINYC__)
591 #define JSON_HEDLEY_TINYC_VERSION JSON_HEDLEY_VERSION_ENCODE(__TINYC__ / 1000, (__TINYC__ / 100) % 10, __TINYC__ % 100)
592#endif
593
594#if defined(JSON_HEDLEY_TINYC_VERSION_CHECK)
595 #undef JSON_HEDLEY_TINYC_VERSION_CHECK
596#endif
597#if defined(JSON_HEDLEY_TINYC_VERSION)
598 #define JSON_HEDLEY_TINYC_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_TINYC_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
599#else
600 #define JSON_HEDLEY_TINYC_VERSION_CHECK(major,minor,patch) (0)
601#endif
602
603#if defined(JSON_HEDLEY_DMC_VERSION)
604 #undef JSON_HEDLEY_DMC_VERSION
605#endif
606#if defined(__DMC__)
607 #define JSON_HEDLEY_DMC_VERSION JSON_HEDLEY_VERSION_ENCODE(__DMC__ >> 8, (__DMC__ >> 4) & 0xf, __DMC__ & 0xf)
608#endif
609
610#if defined(JSON_HEDLEY_DMC_VERSION_CHECK)
611 #undef JSON_HEDLEY_DMC_VERSION_CHECK
612#endif
613#if defined(JSON_HEDLEY_DMC_VERSION)
614 #define JSON_HEDLEY_DMC_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_DMC_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
615#else
616 #define JSON_HEDLEY_DMC_VERSION_CHECK(major,minor,patch) (0)
617#endif
618
619#if defined(JSON_HEDLEY_COMPCERT_VERSION)
620 #undef JSON_HEDLEY_COMPCERT_VERSION
621#endif
622#if defined(__COMPCERT_VERSION__)
623 #define JSON_HEDLEY_COMPCERT_VERSION JSON_HEDLEY_VERSION_ENCODE(__COMPCERT_VERSION__ / 10000, (__COMPCERT_VERSION__ / 100) % 100, __COMPCERT_VERSION__ % 100)
624#endif
625
626#if defined(JSON_HEDLEY_COMPCERT_VERSION_CHECK)
627 #undef JSON_HEDLEY_COMPCERT_VERSION_CHECK
628#endif
629#if defined(JSON_HEDLEY_COMPCERT_VERSION)
630 #define JSON_HEDLEY_COMPCERT_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_COMPCERT_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
631#else
632 #define JSON_HEDLEY_COMPCERT_VERSION_CHECK(major,minor,patch) (0)
633#endif
634
635#if defined(JSON_HEDLEY_PELLES_VERSION)
636 #undef JSON_HEDLEY_PELLES_VERSION
637#endif
638#if defined(__POCC__)
639 #define JSON_HEDLEY_PELLES_VERSION JSON_HEDLEY_VERSION_ENCODE(__POCC__ / 100, __POCC__ % 100, 0)
640#endif
641
642#if defined(JSON_HEDLEY_PELLES_VERSION_CHECK)
643 #undef JSON_HEDLEY_PELLES_VERSION_CHECK
644#endif
645#if defined(JSON_HEDLEY_PELLES_VERSION)
646 #define JSON_HEDLEY_PELLES_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_PELLES_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
647#else
648 #define JSON_HEDLEY_PELLES_VERSION_CHECK(major,minor,patch) (0)
649#endif
650
651#if defined(JSON_HEDLEY_MCST_LCC_VERSION)
652 #undef JSON_HEDLEY_MCST_LCC_VERSION
653#endif
654#if defined(__LCC__) && defined(__LCC_MINOR__)
655 #define JSON_HEDLEY_MCST_LCC_VERSION JSON_HEDLEY_VERSION_ENCODE(__LCC__ / 100, __LCC__ % 100, __LCC_MINOR__)
656#endif
657
658#if defined(JSON_HEDLEY_MCST_LCC_VERSION_CHECK)
659 #undef JSON_HEDLEY_MCST_LCC_VERSION_CHECK
660#endif
661#if defined(JSON_HEDLEY_MCST_LCC_VERSION)
662 #define JSON_HEDLEY_MCST_LCC_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_MCST_LCC_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
663#else
664 #define JSON_HEDLEY_MCST_LCC_VERSION_CHECK(major,minor,patch) (0)
665#endif
666
667#if defined(JSON_HEDLEY_GCC_VERSION)
668 #undef JSON_HEDLEY_GCC_VERSION
669#endif
670#if \
671 defined(JSON_HEDLEY_GNUC_VERSION) && \
672 !defined(__clang__) && \
673 !defined(JSON_HEDLEY_INTEL_VERSION) && \
674 !defined(JSON_HEDLEY_PGI_VERSION) && \
675 !defined(JSON_HEDLEY_ARM_VERSION) && \
676 !defined(JSON_HEDLEY_CRAY_VERSION) && \
677 !defined(JSON_HEDLEY_TI_VERSION) && \
678 !defined(JSON_HEDLEY_TI_ARMCL_VERSION) && \
679 !defined(JSON_HEDLEY_TI_CL430_VERSION) && \
680 !defined(JSON_HEDLEY_TI_CL2000_VERSION) && \
681 !defined(JSON_HEDLEY_TI_CL6X_VERSION) && \
682 !defined(JSON_HEDLEY_TI_CL7X_VERSION) && \
683 !defined(JSON_HEDLEY_TI_CLPRU_VERSION) && \
684 !defined(__COMPCERT__) && \
685 !defined(JSON_HEDLEY_MCST_LCC_VERSION)
686 #define JSON_HEDLEY_GCC_VERSION JSON_HEDLEY_GNUC_VERSION
687#endif
688
689#if defined(JSON_HEDLEY_GCC_VERSION_CHECK)
690 #undef JSON_HEDLEY_GCC_VERSION_CHECK
691#endif
692#if defined(JSON_HEDLEY_GCC_VERSION)
693 #define JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_GCC_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
694#else
695 #define JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch) (0)
696#endif
697
698#if defined(JSON_HEDLEY_HAS_ATTRIBUTE)
699 #undef JSON_HEDLEY_HAS_ATTRIBUTE
700#endif
701#if \
702 defined(__has_attribute) && \
703 ( \
704 (!defined(JSON_HEDLEY_IAR_VERSION) || JSON_HEDLEY_IAR_VERSION_CHECK(8,5,9)) \
705 )
706# define JSON_HEDLEY_HAS_ATTRIBUTE(attribute) __has_attribute(attribute)
707#else
708# define JSON_HEDLEY_HAS_ATTRIBUTE(attribute) (0)
709#endif
710
711#if defined(JSON_HEDLEY_GNUC_HAS_ATTRIBUTE)
712 #undef JSON_HEDLEY_GNUC_HAS_ATTRIBUTE
713#endif
714#if defined(__has_attribute)
715 #define JSON_HEDLEY_GNUC_HAS_ATTRIBUTE(attribute,major,minor,patch) JSON_HEDLEY_HAS_ATTRIBUTE(attribute)
716#else
717 #define JSON_HEDLEY_GNUC_HAS_ATTRIBUTE(attribute,major,minor,patch) JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch)
718#endif
719
720#if defined(JSON_HEDLEY_GCC_HAS_ATTRIBUTE)
721 #undef JSON_HEDLEY_GCC_HAS_ATTRIBUTE
722#endif
723#if defined(__has_attribute)
724 #define JSON_HEDLEY_GCC_HAS_ATTRIBUTE(attribute,major,minor,patch) JSON_HEDLEY_HAS_ATTRIBUTE(attribute)
725#else
726 #define JSON_HEDLEY_GCC_HAS_ATTRIBUTE(attribute,major,minor,patch) JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch)
727#endif
728
729#if defined(JSON_HEDLEY_HAS_CPP_ATTRIBUTE)
730 #undef JSON_HEDLEY_HAS_CPP_ATTRIBUTE
731#endif
732#if \
733 defined(__has_cpp_attribute) && \
734 defined(__cplusplus) && \
735 (!defined(JSON_HEDLEY_SUNPRO_VERSION) || JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,15,0))
736 #define JSON_HEDLEY_HAS_CPP_ATTRIBUTE(attribute) __has_cpp_attribute(attribute)
737#else
738 #define JSON_HEDLEY_HAS_CPP_ATTRIBUTE(attribute) (0)
739#endif
740
741#if defined(JSON_HEDLEY_HAS_CPP_ATTRIBUTE_NS)
742 #undef JSON_HEDLEY_HAS_CPP_ATTRIBUTE_NS
743#endif
744#if !defined(__cplusplus) || !defined(__has_cpp_attribute)
745 #define JSON_HEDLEY_HAS_CPP_ATTRIBUTE_NS(ns,attribute) (0)
746#elif \
747 !defined(JSON_HEDLEY_PGI_VERSION) && \
748 !defined(JSON_HEDLEY_IAR_VERSION) && \
749 (!defined(JSON_HEDLEY_SUNPRO_VERSION) || JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,15,0)) && \
750 (!defined(JSON_HEDLEY_MSVC_VERSION) || JSON_HEDLEY_MSVC_VERSION_CHECK(19,20,0))
751 #define JSON_HEDLEY_HAS_CPP_ATTRIBUTE_NS(ns,attribute) JSON_HEDLEY_HAS_CPP_ATTRIBUTE(ns::attribute)
752#else
753 #define JSON_HEDLEY_HAS_CPP_ATTRIBUTE_NS(ns,attribute) (0)
754#endif
755
756#if defined(JSON_HEDLEY_GNUC_HAS_CPP_ATTRIBUTE)
757 #undef JSON_HEDLEY_GNUC_HAS_CPP_ATTRIBUTE
758#endif
759#if defined(__has_cpp_attribute) && defined(__cplusplus)
760 #define JSON_HEDLEY_GNUC_HAS_CPP_ATTRIBUTE(attribute,major,minor,patch) __has_cpp_attribute(attribute)
761#else
762 #define JSON_HEDLEY_GNUC_HAS_CPP_ATTRIBUTE(attribute,major,minor,patch) JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch)
763#endif
764
765#if defined(JSON_HEDLEY_GCC_HAS_CPP_ATTRIBUTE)
766 #undef JSON_HEDLEY_GCC_HAS_CPP_ATTRIBUTE
767#endif
768#if defined(__has_cpp_attribute) && defined(__cplusplus)
769 #define JSON_HEDLEY_GCC_HAS_CPP_ATTRIBUTE(attribute,major,minor,patch) __has_cpp_attribute(attribute)
770#else
771 #define JSON_HEDLEY_GCC_HAS_CPP_ATTRIBUTE(attribute,major,minor,patch) JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch)
772#endif
773
774#if defined(JSON_HEDLEY_HAS_BUILTIN)
775 #undef JSON_HEDLEY_HAS_BUILTIN
776#endif
777#if defined(__has_builtin)
778 #define JSON_HEDLEY_HAS_BUILTIN(builtin) __has_builtin(builtin)
779#else
780 #define JSON_HEDLEY_HAS_BUILTIN(builtin) (0)
781#endif
782
783#if defined(JSON_HEDLEY_GNUC_HAS_BUILTIN)
784 #undef JSON_HEDLEY_GNUC_HAS_BUILTIN
785#endif
786#if defined(__has_builtin)
787 #define JSON_HEDLEY_GNUC_HAS_BUILTIN(builtin,major,minor,patch) __has_builtin(builtin)
788#else
789 #define JSON_HEDLEY_GNUC_HAS_BUILTIN(builtin,major,minor,patch) JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch)
790#endif
791
792#if defined(JSON_HEDLEY_GCC_HAS_BUILTIN)
793 #undef JSON_HEDLEY_GCC_HAS_BUILTIN
794#endif
795#if defined(__has_builtin)
796 #define JSON_HEDLEY_GCC_HAS_BUILTIN(builtin,major,minor,patch) __has_builtin(builtin)
797#else
798 #define JSON_HEDLEY_GCC_HAS_BUILTIN(builtin,major,minor,patch) JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch)
799#endif
800
801#if defined(JSON_HEDLEY_HAS_FEATURE)
802 #undef JSON_HEDLEY_HAS_FEATURE
803#endif
804#if defined(__has_feature)
805 #define JSON_HEDLEY_HAS_FEATURE(feature) __has_feature(feature)
806#else
807 #define JSON_HEDLEY_HAS_FEATURE(feature) (0)
808#endif
809
810#if defined(JSON_HEDLEY_GNUC_HAS_FEATURE)
811 #undef JSON_HEDLEY_GNUC_HAS_FEATURE
812#endif
813#if defined(__has_feature)
814 #define JSON_HEDLEY_GNUC_HAS_FEATURE(feature,major,minor,patch) __has_feature(feature)
815#else
816 #define JSON_HEDLEY_GNUC_HAS_FEATURE(feature,major,minor,patch) JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch)
817#endif
818
819#if defined(JSON_HEDLEY_GCC_HAS_FEATURE)
820 #undef JSON_HEDLEY_GCC_HAS_FEATURE
821#endif
822#if defined(__has_feature)
823 #define JSON_HEDLEY_GCC_HAS_FEATURE(feature,major,minor,patch) __has_feature(feature)
824#else
825 #define JSON_HEDLEY_GCC_HAS_FEATURE(feature,major,minor,patch) JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch)
826#endif
827
828#if defined(JSON_HEDLEY_HAS_EXTENSION)
829 #undef JSON_HEDLEY_HAS_EXTENSION
830#endif
831#if defined(__has_extension)
832 #define JSON_HEDLEY_HAS_EXTENSION(extension) __has_extension(extension)
833#else
834 #define JSON_HEDLEY_HAS_EXTENSION(extension) (0)
835#endif
836
837#if defined(JSON_HEDLEY_GNUC_HAS_EXTENSION)
838 #undef JSON_HEDLEY_GNUC_HAS_EXTENSION
839#endif
840#if defined(__has_extension)
841 #define JSON_HEDLEY_GNUC_HAS_EXTENSION(extension,major,minor,patch) __has_extension(extension)
842#else
843 #define JSON_HEDLEY_GNUC_HAS_EXTENSION(extension,major,minor,patch) JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch)
844#endif
845
846#if defined(JSON_HEDLEY_GCC_HAS_EXTENSION)
847 #undef JSON_HEDLEY_GCC_HAS_EXTENSION
848#endif
849#if defined(__has_extension)
850 #define JSON_HEDLEY_GCC_HAS_EXTENSION(extension,major,minor,patch) __has_extension(extension)
851#else
852 #define JSON_HEDLEY_GCC_HAS_EXTENSION(extension,major,minor,patch) JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch)
853#endif
854
855#if defined(JSON_HEDLEY_HAS_DECLSPEC_ATTRIBUTE)
856 #undef JSON_HEDLEY_HAS_DECLSPEC_ATTRIBUTE
857#endif
858#if defined(__has_declspec_attribute)
859 #define JSON_HEDLEY_HAS_DECLSPEC_ATTRIBUTE(attribute) __has_declspec_attribute(attribute)
860#else
861 #define JSON_HEDLEY_HAS_DECLSPEC_ATTRIBUTE(attribute) (0)
862#endif
863
864#if defined(JSON_HEDLEY_GNUC_HAS_DECLSPEC_ATTRIBUTE)
865 #undef JSON_HEDLEY_GNUC_HAS_DECLSPEC_ATTRIBUTE
866#endif
867#if defined(__has_declspec_attribute)
868 #define JSON_HEDLEY_GNUC_HAS_DECLSPEC_ATTRIBUTE(attribute,major,minor,patch) __has_declspec_attribute(attribute)
869#else
870 #define JSON_HEDLEY_GNUC_HAS_DECLSPEC_ATTRIBUTE(attribute,major,minor,patch) JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch)
871#endif
872
873#if defined(JSON_HEDLEY_GCC_HAS_DECLSPEC_ATTRIBUTE)
874 #undef JSON_HEDLEY_GCC_HAS_DECLSPEC_ATTRIBUTE
875#endif
876#if defined(__has_declspec_attribute)
877 #define JSON_HEDLEY_GCC_HAS_DECLSPEC_ATTRIBUTE(attribute,major,minor,patch) __has_declspec_attribute(attribute)
878#else
879 #define JSON_HEDLEY_GCC_HAS_DECLSPEC_ATTRIBUTE(attribute,major,minor,patch) JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch)
880#endif
881
882#if defined(JSON_HEDLEY_HAS_WARNING)
883 #undef JSON_HEDLEY_HAS_WARNING
884#endif
885#if defined(__has_warning)
886 #define JSON_HEDLEY_HAS_WARNING(warning) __has_warning(warning)
887#else
888 #define JSON_HEDLEY_HAS_WARNING(warning) (0)
889#endif
890
891#if defined(JSON_HEDLEY_GNUC_HAS_WARNING)
892 #undef JSON_HEDLEY_GNUC_HAS_WARNING
893#endif
894#if defined(__has_warning)
895 #define JSON_HEDLEY_GNUC_HAS_WARNING(warning,major,minor,patch) __has_warning(warning)
896#else
897 #define JSON_HEDLEY_GNUC_HAS_WARNING(warning,major,minor,patch) JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch)
898#endif
899
900#if defined(JSON_HEDLEY_GCC_HAS_WARNING)
901 #undef JSON_HEDLEY_GCC_HAS_WARNING
902#endif
903#if defined(__has_warning)
904 #define JSON_HEDLEY_GCC_HAS_WARNING(warning,major,minor,patch) __has_warning(warning)
905#else
906 #define JSON_HEDLEY_GCC_HAS_WARNING(warning,major,minor,patch) JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch)
907#endif
908
909#if \
910 (defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L)) || \
911 defined(__clang__) || \
912 JSON_HEDLEY_GCC_VERSION_CHECK(3,0,0) || \
913 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
914 JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0) || \
915 JSON_HEDLEY_PGI_VERSION_CHECK(18,4,0) || \
916 JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
917 JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \
918 JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,7,0) || \
919 JSON_HEDLEY_TI_CL430_VERSION_CHECK(2,0,1) || \
920 JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,1,0) || \
921 JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,0,0) || \
922 JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
923 JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \
924 JSON_HEDLEY_CRAY_VERSION_CHECK(5,0,0) || \
925 JSON_HEDLEY_TINYC_VERSION_CHECK(0,9,17) || \
926 JSON_HEDLEY_SUNPRO_VERSION_CHECK(8,0,0) || \
927 (JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) && defined(__C99_PRAGMA_OPERATOR))
928 #define JSON_HEDLEY_PRAGMA(value) _Pragma(#value)
929#elif JSON_HEDLEY_MSVC_VERSION_CHECK(15,0,0)
930 #define JSON_HEDLEY_PRAGMA(value) __pragma(value)
931#else
932 #define JSON_HEDLEY_PRAGMA(value)
933#endif
934
935#if defined(JSON_HEDLEY_DIAGNOSTIC_PUSH)
936 #undef JSON_HEDLEY_DIAGNOSTIC_PUSH
937#endif
938#if defined(JSON_HEDLEY_DIAGNOSTIC_POP)
939 #undef JSON_HEDLEY_DIAGNOSTIC_POP
940#endif
941#if defined(__clang__)
942 #define JSON_HEDLEY_DIAGNOSTIC_PUSH _Pragma("clang diagnostic push")
943 #define JSON_HEDLEY_DIAGNOSTIC_POP _Pragma("clang diagnostic pop")
944#elif JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0)
945 #define JSON_HEDLEY_DIAGNOSTIC_PUSH _Pragma("warning(push)")
946 #define JSON_HEDLEY_DIAGNOSTIC_POP _Pragma("warning(pop)")
947#elif JSON_HEDLEY_GCC_VERSION_CHECK(4,6,0)
948 #define JSON_HEDLEY_DIAGNOSTIC_PUSH _Pragma("GCC diagnostic push")
949 #define JSON_HEDLEY_DIAGNOSTIC_POP _Pragma("GCC diagnostic pop")
950#elif \
951 JSON_HEDLEY_MSVC_VERSION_CHECK(15,0,0) || \
952 JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0)
953 #define JSON_HEDLEY_DIAGNOSTIC_PUSH __pragma(warning(push))
954 #define JSON_HEDLEY_DIAGNOSTIC_POP __pragma(warning(pop))
955#elif JSON_HEDLEY_ARM_VERSION_CHECK(5,6,0)
956 #define JSON_HEDLEY_DIAGNOSTIC_PUSH _Pragma("push")
957 #define JSON_HEDLEY_DIAGNOSTIC_POP _Pragma("pop")
958#elif \
959 JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \
960 JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \
961 JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,4,0) || \
962 JSON_HEDLEY_TI_CL6X_VERSION_CHECK(8,1,0) || \
963 JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
964 JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0)
965 #define JSON_HEDLEY_DIAGNOSTIC_PUSH _Pragma("diag_push")
966 #define JSON_HEDLEY_DIAGNOSTIC_POP _Pragma("diag_pop")
967#elif JSON_HEDLEY_PELLES_VERSION_CHECK(2,90,0)
968 #define JSON_HEDLEY_DIAGNOSTIC_PUSH _Pragma("warning(push)")
969 #define JSON_HEDLEY_DIAGNOSTIC_POP _Pragma("warning(pop)")
970#else
971 #define JSON_HEDLEY_DIAGNOSTIC_PUSH
972 #define JSON_HEDLEY_DIAGNOSTIC_POP
973#endif
974
975/* JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_ is for
976 HEDLEY INTERNAL USE ONLY. API subject to change without notice. */
977#if defined(JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_)
978 #undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_
979#endif
980#if defined(__cplusplus)
981# if JSON_HEDLEY_HAS_WARNING("-Wc++98-compat")
982# if JSON_HEDLEY_HAS_WARNING("-Wc++17-extensions")
983# if JSON_HEDLEY_HAS_WARNING("-Wc++1z-extensions")
984# define JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_(xpr) \
985 JSON_HEDLEY_DIAGNOSTIC_PUSH \
986 _Pragma("clang diagnostic ignored \"-Wc++98-compat\"") \
987 _Pragma("clang diagnostic ignored \"-Wc++17-extensions\"") \
988 _Pragma("clang diagnostic ignored \"-Wc++1z-extensions\"") \
989 xpr \
990 JSON_HEDLEY_DIAGNOSTIC_POP
991# else
992# define JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_(xpr) \
993 JSON_HEDLEY_DIAGNOSTIC_PUSH \
994 _Pragma("clang diagnostic ignored \"-Wc++98-compat\"") \
995 _Pragma("clang diagnostic ignored \"-Wc++17-extensions\"") \
996 xpr \
997 JSON_HEDLEY_DIAGNOSTIC_POP
998# endif
999# else
1000# define JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_(xpr) \
1001 JSON_HEDLEY_DIAGNOSTIC_PUSH \
1002 _Pragma("clang diagnostic ignored \"-Wc++98-compat\"") \
1003 xpr \
1004 JSON_HEDLEY_DIAGNOSTIC_POP
1005# endif
1006# endif
1007#endif
1008#if !defined(JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_)
1009 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_(x) x
1010#endif
1011
1012#if defined(JSON_HEDLEY_CONST_CAST)
1013 #undef JSON_HEDLEY_CONST_CAST
1014#endif
1015#if defined(__cplusplus)
1016# define JSON_HEDLEY_CONST_CAST(T, expr) (const_cast<T>(expr))
1017#elif \
1018 JSON_HEDLEY_HAS_WARNING("-Wcast-qual") || \
1019 JSON_HEDLEY_GCC_VERSION_CHECK(4,6,0) || \
1020 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0)
1021# define JSON_HEDLEY_CONST_CAST(T, expr) (__extension__ ({ \
1022 JSON_HEDLEY_DIAGNOSTIC_PUSH \
1023 JSON_HEDLEY_DIAGNOSTIC_DISABLE_CAST_QUAL \
1024 ((T) (expr)); \
1025 JSON_HEDLEY_DIAGNOSTIC_POP \
1026 }))
1027#else
1028# define JSON_HEDLEY_CONST_CAST(T, expr) ((T) (expr))
1029#endif
1030
1031#if defined(JSON_HEDLEY_REINTERPRET_CAST)
1032 #undef JSON_HEDLEY_REINTERPRET_CAST
1033#endif
1034#if defined(__cplusplus)
1035 #define JSON_HEDLEY_REINTERPRET_CAST(T, expr) (reinterpret_cast<T>(expr))
1036#else
1037 #define JSON_HEDLEY_REINTERPRET_CAST(T, expr) ((T) (expr))
1038#endif
1039
1040#if defined(JSON_HEDLEY_STATIC_CAST)
1041 #undef JSON_HEDLEY_STATIC_CAST
1042#endif
1043#if defined(__cplusplus)
1044 #define JSON_HEDLEY_STATIC_CAST(T, expr) (static_cast<T>(expr))
1045#else
1046 #define JSON_HEDLEY_STATIC_CAST(T, expr) ((T) (expr))
1047#endif
1048
1049#if defined(JSON_HEDLEY_CPP_CAST)
1050 #undef JSON_HEDLEY_CPP_CAST
1051#endif
1052#if defined(__cplusplus)
1053# if JSON_HEDLEY_HAS_WARNING("-Wold-style-cast")
1054# define JSON_HEDLEY_CPP_CAST(T, expr) \
1055 JSON_HEDLEY_DIAGNOSTIC_PUSH \
1056 _Pragma("clang diagnostic ignored \"-Wold-style-cast\"") \
1057 ((T) (expr)) \
1058 JSON_HEDLEY_DIAGNOSTIC_POP
1059# elif JSON_HEDLEY_IAR_VERSION_CHECK(8,3,0)
1060# define JSON_HEDLEY_CPP_CAST(T, expr) \
1061 JSON_HEDLEY_DIAGNOSTIC_PUSH \
1062 _Pragma("diag_suppress=Pe137") \
1063 JSON_HEDLEY_DIAGNOSTIC_POP
1064# else
1065# define JSON_HEDLEY_CPP_CAST(T, expr) ((T) (expr))
1066# endif
1067#else
1068# define JSON_HEDLEY_CPP_CAST(T, expr) (expr)
1069#endif
1070
1071#if defined(JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED)
1072 #undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED
1073#endif
1074#if JSON_HEDLEY_HAS_WARNING("-Wdeprecated-declarations")
1075 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("clang diagnostic ignored \"-Wdeprecated-declarations\"")
1076#elif JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0)
1077 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("warning(disable:1478 1786)")
1078#elif JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0)
1079 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED __pragma(warning(disable:1478 1786))
1080#elif JSON_HEDLEY_PGI_VERSION_CHECK(20,7,0)
1081 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("diag_suppress 1215,1216,1444,1445")
1082#elif JSON_HEDLEY_PGI_VERSION_CHECK(17,10,0)
1083 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("diag_suppress 1215,1444")
1084#elif JSON_HEDLEY_GCC_VERSION_CHECK(4,3,0)
1085 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("GCC diagnostic ignored \"-Wdeprecated-declarations\"")
1086#elif JSON_HEDLEY_MSVC_VERSION_CHECK(15,0,0)
1087 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED __pragma(warning(disable:4996))
1088#elif JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1089 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("diag_suppress 1215,1444")
1090#elif \
1091 JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \
1092 (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1093 JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \
1094 (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1095 JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \
1096 (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1097 JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \
1098 (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1099 JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \
1100 JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1101 JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0)
1102 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("diag_suppress 1291,1718")
1103#elif JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,13,0) && !defined(__cplusplus)
1104 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("error_messages(off,E_DEPRECATED_ATT,E_DEPRECATED_ATT_MESS)")
1105#elif JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,13,0) && defined(__cplusplus)
1106 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("error_messages(off,symdeprecated,symdeprecated2)")
1107#elif JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0)
1108 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("diag_suppress=Pe1444,Pe1215")
1109#elif JSON_HEDLEY_PELLES_VERSION_CHECK(2,90,0)
1110 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("warn(disable:2241)")
1111#else
1112 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED
1113#endif
1114
1115#if defined(JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS)
1116 #undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS
1117#endif
1118#if JSON_HEDLEY_HAS_WARNING("-Wunknown-pragmas")
1119 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS _Pragma("clang diagnostic ignored \"-Wunknown-pragmas\"")
1120#elif JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0)
1121 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS _Pragma("warning(disable:161)")
1122#elif JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0)
1123 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS __pragma(warning(disable:161))
1124#elif JSON_HEDLEY_PGI_VERSION_CHECK(17,10,0)
1125 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS _Pragma("diag_suppress 1675")
1126#elif JSON_HEDLEY_GCC_VERSION_CHECK(4,3,0)
1127 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS _Pragma("GCC diagnostic ignored \"-Wunknown-pragmas\"")
1128#elif JSON_HEDLEY_MSVC_VERSION_CHECK(15,0,0)
1129 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS __pragma(warning(disable:4068))
1130#elif \
1131 JSON_HEDLEY_TI_VERSION_CHECK(16,9,0) || \
1132 JSON_HEDLEY_TI_CL6X_VERSION_CHECK(8,0,0) || \
1133 JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1134 JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,3,0)
1135 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS _Pragma("diag_suppress 163")
1136#elif JSON_HEDLEY_TI_CL6X_VERSION_CHECK(8,0,0)
1137 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS _Pragma("diag_suppress 163")
1138#elif JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0)
1139 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS _Pragma("diag_suppress=Pe161")
1140#elif JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1141 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS _Pragma("diag_suppress 161")
1142#else
1143 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS
1144#endif
1145
1146#if defined(JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES)
1147 #undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES
1148#endif
1149#if JSON_HEDLEY_HAS_WARNING("-Wunknown-attributes")
1150 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma("clang diagnostic ignored \"-Wunknown-attributes\"")
1151#elif JSON_HEDLEY_GCC_VERSION_CHECK(4,6,0)
1152 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma("GCC diagnostic ignored \"-Wdeprecated-declarations\"")
1153#elif JSON_HEDLEY_INTEL_VERSION_CHECK(17,0,0)
1154 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma("warning(disable:1292)")
1155#elif JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0)
1156 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES __pragma(warning(disable:1292))
1157#elif JSON_HEDLEY_MSVC_VERSION_CHECK(19,0,0)
1158 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES __pragma(warning(disable:5030))
1159#elif JSON_HEDLEY_PGI_VERSION_CHECK(20,7,0)
1160 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma("diag_suppress 1097,1098")
1161#elif JSON_HEDLEY_PGI_VERSION_CHECK(17,10,0)
1162 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma("diag_suppress 1097")
1163#elif JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,14,0) && defined(__cplusplus)
1164 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma("error_messages(off,attrskipunsup)")
1165#elif \
1166 JSON_HEDLEY_TI_VERSION_CHECK(18,1,0) || \
1167 JSON_HEDLEY_TI_CL6X_VERSION_CHECK(8,3,0) || \
1168 JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0)
1169 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma("diag_suppress 1173")
1170#elif JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0)
1171 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma("diag_suppress=Pe1097")
1172#elif JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1173 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma("diag_suppress 1097")
1174#else
1175 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES
1176#endif
1177
1178#if defined(JSON_HEDLEY_DIAGNOSTIC_DISABLE_CAST_QUAL)
1179 #undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_CAST_QUAL
1180#endif
1181#if JSON_HEDLEY_HAS_WARNING("-Wcast-qual")
1182 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_CAST_QUAL _Pragma("clang diagnostic ignored \"-Wcast-qual\"")
1183#elif JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0)
1184 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_CAST_QUAL _Pragma("warning(disable:2203 2331)")
1185#elif JSON_HEDLEY_GCC_VERSION_CHECK(3,0,0)
1186 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_CAST_QUAL _Pragma("GCC diagnostic ignored \"-Wcast-qual\"")
1187#else
1188 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_CAST_QUAL
1189#endif
1190
1191#if defined(JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNUSED_FUNCTION)
1192 #undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNUSED_FUNCTION
1193#endif
1194#if JSON_HEDLEY_HAS_WARNING("-Wunused-function")
1195 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNUSED_FUNCTION _Pragma("clang diagnostic ignored \"-Wunused-function\"")
1196#elif JSON_HEDLEY_GCC_VERSION_CHECK(3,4,0)
1197 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNUSED_FUNCTION _Pragma("GCC diagnostic ignored \"-Wunused-function\"")
1198#elif JSON_HEDLEY_MSVC_VERSION_CHECK(1,0,0)
1199 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNUSED_FUNCTION __pragma(warning(disable:4505))
1200#elif JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1201 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNUSED_FUNCTION _Pragma("diag_suppress 3142")
1202#else
1203 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNUSED_FUNCTION
1204#endif
1205
1206#if defined(JSON_HEDLEY_DEPRECATED)
1207 #undef JSON_HEDLEY_DEPRECATED
1208#endif
1209#if defined(JSON_HEDLEY_DEPRECATED_FOR)
1210 #undef JSON_HEDLEY_DEPRECATED_FOR
1211#endif
1212#if \
1213 JSON_HEDLEY_MSVC_VERSION_CHECK(14,0,0) || \
1214 JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0)
1215 #define JSON_HEDLEY_DEPRECATED(since) __declspec(deprecated("Since " # since))
1216 #define JSON_HEDLEY_DEPRECATED_FOR(since, replacement) __declspec(deprecated("Since " #since "; use " #replacement))
1217#elif \
1218 (JSON_HEDLEY_HAS_EXTENSION(attribute_deprecated_with_message) && !defined(JSON_HEDLEY_IAR_VERSION)) || \
1219 JSON_HEDLEY_GCC_VERSION_CHECK(4,5,0) || \
1220 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1221 JSON_HEDLEY_ARM_VERSION_CHECK(5,6,0) || \
1222 JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,13,0) || \
1223 JSON_HEDLEY_PGI_VERSION_CHECK(17,10,0) || \
1224 JSON_HEDLEY_TI_VERSION_CHECK(18,1,0) || \
1225 JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(18,1,0) || \
1226 JSON_HEDLEY_TI_CL6X_VERSION_CHECK(8,3,0) || \
1227 JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1228 JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,3,0) || \
1229 JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1230 #define JSON_HEDLEY_DEPRECATED(since) __attribute__((__deprecated__("Since " #since)))
1231 #define JSON_HEDLEY_DEPRECATED_FOR(since, replacement) __attribute__((__deprecated__("Since " #since "; use " #replacement)))
1232#elif defined(__cplusplus) && (__cplusplus >= 201402L)
1233 #define JSON_HEDLEY_DEPRECATED(since) JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[deprecated("Since " #since)]])
1234 #define JSON_HEDLEY_DEPRECATED_FOR(since, replacement) JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[deprecated("Since " #since "; use " #replacement)]])
1235#elif \
1236 JSON_HEDLEY_HAS_ATTRIBUTE(deprecated) || \
1237 JSON_HEDLEY_GCC_VERSION_CHECK(3,1,0) || \
1238 JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
1239 JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \
1240 (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1241 JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \
1242 (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1243 JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \
1244 (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1245 JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \
1246 (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1247 JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \
1248 JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1249 JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \
1250 JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10) || \
1251 JSON_HEDLEY_IAR_VERSION_CHECK(8,10,0)
1252 #define JSON_HEDLEY_DEPRECATED(since) __attribute__((__deprecated__))
1253 #define JSON_HEDLEY_DEPRECATED_FOR(since, replacement) __attribute__((__deprecated__))
1254#elif \
1255 JSON_HEDLEY_MSVC_VERSION_CHECK(13,10,0) || \
1256 JSON_HEDLEY_PELLES_VERSION_CHECK(6,50,0) || \
1257 JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0)
1258 #define JSON_HEDLEY_DEPRECATED(since) __declspec(deprecated)
1259 #define JSON_HEDLEY_DEPRECATED_FOR(since, replacement) __declspec(deprecated)
1260#elif JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0)
1261 #define JSON_HEDLEY_DEPRECATED(since) _Pragma("deprecated")
1262 #define JSON_HEDLEY_DEPRECATED_FOR(since, replacement) _Pragma("deprecated")
1263#else
1264 #define JSON_HEDLEY_DEPRECATED(since)
1265 #define JSON_HEDLEY_DEPRECATED_FOR(since, replacement)
1266#endif
1267
1268#if defined(JSON_HEDLEY_UNAVAILABLE)
1269 #undef JSON_HEDLEY_UNAVAILABLE
1270#endif
1271#if \
1272 JSON_HEDLEY_HAS_ATTRIBUTE(warning) || \
1273 JSON_HEDLEY_GCC_VERSION_CHECK(4,3,0) || \
1274 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1275 JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1276 #define JSON_HEDLEY_UNAVAILABLE(available_since) __attribute__((__warning__("Not available until " #available_since)))
1277#else
1278 #define JSON_HEDLEY_UNAVAILABLE(available_since)
1279#endif
1280
1281#if defined(JSON_HEDLEY_WARN_UNUSED_RESULT)
1282 #undef JSON_HEDLEY_WARN_UNUSED_RESULT
1283#endif
1284#if defined(JSON_HEDLEY_WARN_UNUSED_RESULT_MSG)
1285 #undef JSON_HEDLEY_WARN_UNUSED_RESULT_MSG
1286#endif
1287#if \
1288 JSON_HEDLEY_HAS_ATTRIBUTE(warn_unused_result) || \
1289 JSON_HEDLEY_GCC_VERSION_CHECK(3,4,0) || \
1290 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1291 JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \
1292 (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1293 JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \
1294 (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1295 JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \
1296 (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1297 JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \
1298 (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1299 JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \
1300 JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1301 JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \
1302 (JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,15,0) && defined(__cplusplus)) || \
1303 JSON_HEDLEY_PGI_VERSION_CHECK(17,10,0) || \
1304 JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1305 #define JSON_HEDLEY_WARN_UNUSED_RESULT __attribute__((__warn_unused_result__))
1306 #define JSON_HEDLEY_WARN_UNUSED_RESULT_MSG(msg) __attribute__((__warn_unused_result__))
1307#elif (JSON_HEDLEY_HAS_CPP_ATTRIBUTE(nodiscard) >= 201907L)
1308 #define JSON_HEDLEY_WARN_UNUSED_RESULT JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[nodiscard]])
1309 #define JSON_HEDLEY_WARN_UNUSED_RESULT_MSG(msg) JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[nodiscard(msg)]])
1310#elif JSON_HEDLEY_HAS_CPP_ATTRIBUTE(nodiscard)
1311 #define JSON_HEDLEY_WARN_UNUSED_RESULT JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[nodiscard]])
1312 #define JSON_HEDLEY_WARN_UNUSED_RESULT_MSG(msg) JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[nodiscard]])
1313#elif defined(_Check_return_) /* SAL */
1314 #define JSON_HEDLEY_WARN_UNUSED_RESULT _Check_return_
1315 #define JSON_HEDLEY_WARN_UNUSED_RESULT_MSG(msg) _Check_return_
1316#else
1317 #define JSON_HEDLEY_WARN_UNUSED_RESULT
1318 #define JSON_HEDLEY_WARN_UNUSED_RESULT_MSG(msg)
1319#endif
1320
1321#if defined(JSON_HEDLEY_SENTINEL)
1322 #undef JSON_HEDLEY_SENTINEL
1323#endif
1324#if \
1325 JSON_HEDLEY_HAS_ATTRIBUTE(sentinel) || \
1326 JSON_HEDLEY_GCC_VERSION_CHECK(4,0,0) || \
1327 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1328 JSON_HEDLEY_ARM_VERSION_CHECK(5,4,0) || \
1329 JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1330 #define JSON_HEDLEY_SENTINEL(position) __attribute__((__sentinel__(position)))
1331#else
1332 #define JSON_HEDLEY_SENTINEL(position)
1333#endif
1334
1335#if defined(JSON_HEDLEY_NO_RETURN)
1336 #undef JSON_HEDLEY_NO_RETURN
1337#endif
1338#if JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0)
1339 #define JSON_HEDLEY_NO_RETURN __noreturn
1340#elif \
1341 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1342 JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1343 #define JSON_HEDLEY_NO_RETURN __attribute__((__noreturn__))
1344#elif defined(__STDC_VERSION__) && __STDC_VERSION__ >= 201112L
1345 #define JSON_HEDLEY_NO_RETURN _Noreturn
1346#elif defined(__cplusplus) && (__cplusplus >= 201103L)
1347 #define JSON_HEDLEY_NO_RETURN JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[noreturn]])
1348#elif \
1349 JSON_HEDLEY_HAS_ATTRIBUTE(noreturn) || \
1350 JSON_HEDLEY_GCC_VERSION_CHECK(3,2,0) || \
1351 JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,11,0) || \
1352 JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
1353 JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) || \
1354 JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \
1355 (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1356 JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \
1357 (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1358 JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \
1359 (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1360 JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \
1361 (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1362 JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \
1363 JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1364 JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \
1365 JSON_HEDLEY_IAR_VERSION_CHECK(8,10,0)
1366 #define JSON_HEDLEY_NO_RETURN __attribute__((__noreturn__))
1367#elif JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,10,0)
1368 #define JSON_HEDLEY_NO_RETURN _Pragma("does_not_return")
1369#elif \
1370 JSON_HEDLEY_MSVC_VERSION_CHECK(13,10,0) || \
1371 JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0)
1372 #define JSON_HEDLEY_NO_RETURN __declspec(noreturn)
1373#elif JSON_HEDLEY_TI_CL6X_VERSION_CHECK(6,0,0) && defined(__cplusplus)
1374 #define JSON_HEDLEY_NO_RETURN _Pragma("FUNC_NEVER_RETURNS;")
1375#elif JSON_HEDLEY_COMPCERT_VERSION_CHECK(3,2,0)
1376 #define JSON_HEDLEY_NO_RETURN __attribute((noreturn))
1377#elif JSON_HEDLEY_PELLES_VERSION_CHECK(9,0,0)
1378 #define JSON_HEDLEY_NO_RETURN __declspec(noreturn)
1379#else
1380 #define JSON_HEDLEY_NO_RETURN
1381#endif
1382
1383#if defined(JSON_HEDLEY_NO_ESCAPE)
1384 #undef JSON_HEDLEY_NO_ESCAPE
1385#endif
1386#if JSON_HEDLEY_HAS_ATTRIBUTE(noescape)
1387 #define JSON_HEDLEY_NO_ESCAPE __attribute__((__noescape__))
1388#else
1389 #define JSON_HEDLEY_NO_ESCAPE
1390#endif
1391
1392#if defined(JSON_HEDLEY_UNREACHABLE)
1393 #undef JSON_HEDLEY_UNREACHABLE
1394#endif
1395#if defined(JSON_HEDLEY_UNREACHABLE_RETURN)
1396 #undef JSON_HEDLEY_UNREACHABLE_RETURN
1397#endif
1398#if defined(JSON_HEDLEY_ASSUME)
1399 #undef JSON_HEDLEY_ASSUME
1400#endif
1401#if \
1402 JSON_HEDLEY_MSVC_VERSION_CHECK(13,10,0) || \
1403 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1404 JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0)
1405 #define JSON_HEDLEY_ASSUME(expr) __assume(expr)
1406#elif JSON_HEDLEY_HAS_BUILTIN(__builtin_assume)
1407 #define JSON_HEDLEY_ASSUME(expr) __builtin_assume(expr)
1408#elif \
1409 JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,2,0) || \
1410 JSON_HEDLEY_TI_CL6X_VERSION_CHECK(4,0,0)
1411 #if defined(__cplusplus)
1412 #define JSON_HEDLEY_ASSUME(expr) std::_nassert(expr)
1413 #else
1414 #define JSON_HEDLEY_ASSUME(expr) _nassert(expr)
1415 #endif
1416#endif
1417#if \
1418 (JSON_HEDLEY_HAS_BUILTIN(__builtin_unreachable) && (!defined(JSON_HEDLEY_ARM_VERSION))) || \
1419 JSON_HEDLEY_GCC_VERSION_CHECK(4,5,0) || \
1420 JSON_HEDLEY_PGI_VERSION_CHECK(18,10,0) || \
1421 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1422 JSON_HEDLEY_IBM_VERSION_CHECK(13,1,5) || \
1423 JSON_HEDLEY_CRAY_VERSION_CHECK(10,0,0) || \
1424 JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1425 #define JSON_HEDLEY_UNREACHABLE() __builtin_unreachable()
1426#elif defined(JSON_HEDLEY_ASSUME)
1427 #define JSON_HEDLEY_UNREACHABLE() JSON_HEDLEY_ASSUME(0)
1428#endif
1429#if !defined(JSON_HEDLEY_ASSUME)
1430 #if defined(JSON_HEDLEY_UNREACHABLE)
1431 #define JSON_HEDLEY_ASSUME(expr) JSON_HEDLEY_STATIC_CAST(void, ((expr) ? 1 : (JSON_HEDLEY_UNREACHABLE(), 1)))
1432 #else
1433 #define JSON_HEDLEY_ASSUME(expr) JSON_HEDLEY_STATIC_CAST(void, expr)
1434 #endif
1435#endif
1436#if defined(JSON_HEDLEY_UNREACHABLE)
1437 #if \
1438 JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,2,0) || \
1439 JSON_HEDLEY_TI_CL6X_VERSION_CHECK(4,0,0)
1440 #define JSON_HEDLEY_UNREACHABLE_RETURN(value) return (JSON_HEDLEY_STATIC_CAST(void, JSON_HEDLEY_ASSUME(0)), (value))
1441 #else
1442 #define JSON_HEDLEY_UNREACHABLE_RETURN(value) JSON_HEDLEY_UNREACHABLE()
1443 #endif
1444#else
1445 #define JSON_HEDLEY_UNREACHABLE_RETURN(value) return (value)
1446#endif
1447#if !defined(JSON_HEDLEY_UNREACHABLE)
1448 #define JSON_HEDLEY_UNREACHABLE() JSON_HEDLEY_ASSUME(0)
1449#endif
1450
1452#if JSON_HEDLEY_HAS_WARNING("-Wpedantic")
1453 #pragma clang diagnostic ignored "-Wpedantic"
1454#endif
1455#if JSON_HEDLEY_HAS_WARNING("-Wc++98-compat-pedantic") && defined(__cplusplus)
1456 #pragma clang diagnostic ignored "-Wc++98-compat-pedantic"
1457#endif
1458#if JSON_HEDLEY_GCC_HAS_WARNING("-Wvariadic-macros",4,0,0)
1459 #if defined(__clang__)
1460 #pragma clang diagnostic ignored "-Wvariadic-macros"
1461 #elif defined(JSON_HEDLEY_GCC_VERSION)
1462 #pragma GCC diagnostic ignored "-Wvariadic-macros"
1463 #endif
1464#endif
1465#if defined(JSON_HEDLEY_NON_NULL)
1466 #undef JSON_HEDLEY_NON_NULL
1467#endif
1468#if \
1469 JSON_HEDLEY_HAS_ATTRIBUTE(nonnull) || \
1470 JSON_HEDLEY_GCC_VERSION_CHECK(3,3,0) || \
1471 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1472 JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0)
1473 #define JSON_HEDLEY_NON_NULL(...) __attribute__((__nonnull__(__VA_ARGS__)))
1474#else
1475 #define JSON_HEDLEY_NON_NULL(...)
1476#endif
1478
1479#if defined(JSON_HEDLEY_PRINTF_FORMAT)
1480 #undef JSON_HEDLEY_PRINTF_FORMAT
1481#endif
1482#if defined(__MINGW32__) && JSON_HEDLEY_GCC_HAS_ATTRIBUTE(format,4,4,0) && !defined(__USE_MINGW_ANSI_STDIO)
1483 #define JSON_HEDLEY_PRINTF_FORMAT(string_idx,first_to_check) __attribute__((__format__(ms_printf, string_idx, first_to_check)))
1484#elif defined(__MINGW32__) && JSON_HEDLEY_GCC_HAS_ATTRIBUTE(format,4,4,0) && defined(__USE_MINGW_ANSI_STDIO)
1485 #define JSON_HEDLEY_PRINTF_FORMAT(string_idx,first_to_check) __attribute__((__format__(gnu_printf, string_idx, first_to_check)))
1486#elif \
1487 JSON_HEDLEY_HAS_ATTRIBUTE(format) || \
1488 JSON_HEDLEY_GCC_VERSION_CHECK(3,1,0) || \
1489 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1490 JSON_HEDLEY_ARM_VERSION_CHECK(5,6,0) || \
1491 JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) || \
1492 JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \
1493 (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1494 JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \
1495 (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1496 JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \
1497 (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1498 JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \
1499 (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1500 JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \
1501 JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1502 JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \
1503 JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1504 #define JSON_HEDLEY_PRINTF_FORMAT(string_idx,first_to_check) __attribute__((__format__(__printf__, string_idx, first_to_check)))
1505#elif JSON_HEDLEY_PELLES_VERSION_CHECK(6,0,0)
1506 #define JSON_HEDLEY_PRINTF_FORMAT(string_idx,first_to_check) __declspec(vaformat(printf,string_idx,first_to_check))
1507#else
1508 #define JSON_HEDLEY_PRINTF_FORMAT(string_idx,first_to_check)
1509#endif
1510
1511#if defined(JSON_HEDLEY_CONSTEXPR)
1512 #undef JSON_HEDLEY_CONSTEXPR
1513#endif
1514#if defined(__cplusplus)
1515 #if __cplusplus >= 201103L
1516 #define JSON_HEDLEY_CONSTEXPR JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_(constexpr)
1517 #endif
1518#endif
1519#if !defined(JSON_HEDLEY_CONSTEXPR)
1520 #define JSON_HEDLEY_CONSTEXPR
1521#endif
1522
1523#if defined(JSON_HEDLEY_PREDICT)
1524 #undef JSON_HEDLEY_PREDICT
1525#endif
1526#if defined(JSON_HEDLEY_LIKELY)
1527 #undef JSON_HEDLEY_LIKELY
1528#endif
1529#if defined(JSON_HEDLEY_UNLIKELY)
1530 #undef JSON_HEDLEY_UNLIKELY
1531#endif
1532#if defined(JSON_HEDLEY_UNPREDICTABLE)
1533 #undef JSON_HEDLEY_UNPREDICTABLE
1534#endif
1535#if JSON_HEDLEY_HAS_BUILTIN(__builtin_unpredictable)
1536 #define JSON_HEDLEY_UNPREDICTABLE(expr) __builtin_unpredictable((expr))
1537#endif
1538#if \
1539 (JSON_HEDLEY_HAS_BUILTIN(__builtin_expect_with_probability) && !defined(JSON_HEDLEY_PGI_VERSION)) || \
1540 JSON_HEDLEY_GCC_VERSION_CHECK(9,0,0) || \
1541 JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1542# define JSON_HEDLEY_PREDICT(expr, value, probability) __builtin_expect_with_probability( (expr), (value), (probability))
1543# define JSON_HEDLEY_PREDICT_TRUE(expr, probability) __builtin_expect_with_probability(!!(expr), 1 , (probability))
1544# define JSON_HEDLEY_PREDICT_FALSE(expr, probability) __builtin_expect_with_probability(!!(expr), 0 , (probability))
1545# define JSON_HEDLEY_LIKELY(expr) __builtin_expect (!!(expr), 1 )
1546# define JSON_HEDLEY_UNLIKELY(expr) __builtin_expect (!!(expr), 0 )
1547#elif \
1548 (JSON_HEDLEY_HAS_BUILTIN(__builtin_expect) && !defined(JSON_HEDLEY_INTEL_CL_VERSION)) || \
1549 JSON_HEDLEY_GCC_VERSION_CHECK(3,0,0) || \
1550 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1551 (JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,15,0) && defined(__cplusplus)) || \
1552 JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
1553 JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) || \
1554 JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \
1555 JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,7,0) || \
1556 JSON_HEDLEY_TI_CL430_VERSION_CHECK(3,1,0) || \
1557 JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,1,0) || \
1558 JSON_HEDLEY_TI_CL6X_VERSION_CHECK(6,1,0) || \
1559 JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1560 JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \
1561 JSON_HEDLEY_TINYC_VERSION_CHECK(0,9,27) || \
1562 JSON_HEDLEY_CRAY_VERSION_CHECK(8,1,0) || \
1563 JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1564# define JSON_HEDLEY_PREDICT(expr, expected, probability) \
1565 (((probability) >= 0.9) ? __builtin_expect((expr), (expected)) : (JSON_HEDLEY_STATIC_CAST(void, expected), (expr)))
1566# define JSON_HEDLEY_PREDICT_TRUE(expr, probability) \
1567 (__extension__ ({ \
1568 double hedley_probability_ = (probability); \
1569 ((hedley_probability_ >= 0.9) ? __builtin_expect(!!(expr), 1) : ((hedley_probability_ <= 0.1) ? __builtin_expect(!!(expr), 0) : !!(expr))); \
1570 }))
1571# define JSON_HEDLEY_PREDICT_FALSE(expr, probability) \
1572 (__extension__ ({ \
1573 double hedley_probability_ = (probability); \
1574 ((hedley_probability_ >= 0.9) ? __builtin_expect(!!(expr), 0) : ((hedley_probability_ <= 0.1) ? __builtin_expect(!!(expr), 1) : !!(expr))); \
1575 }))
1576# define JSON_HEDLEY_LIKELY(expr) __builtin_expect(!!(expr), 1)
1577# define JSON_HEDLEY_UNLIKELY(expr) __builtin_expect(!!(expr), 0)
1578#else
1579# define JSON_HEDLEY_PREDICT(expr, expected, probability) (JSON_HEDLEY_STATIC_CAST(void, expected), (expr))
1580# define JSON_HEDLEY_PREDICT_TRUE(expr, probability) (!!(expr))
1581# define JSON_HEDLEY_PREDICT_FALSE(expr, probability) (!!(expr))
1582# define JSON_HEDLEY_LIKELY(expr) (!!(expr))
1583# define JSON_HEDLEY_UNLIKELY(expr) (!!(expr))
1584#endif
1585#if !defined(JSON_HEDLEY_UNPREDICTABLE)
1586 #define JSON_HEDLEY_UNPREDICTABLE(expr) JSON_HEDLEY_PREDICT(expr, 1, 0.5)
1587#endif
1588
1589#if defined(JSON_HEDLEY_MALLOC)
1590 #undef JSON_HEDLEY_MALLOC
1591#endif
1592#if \
1593 JSON_HEDLEY_HAS_ATTRIBUTE(malloc) || \
1594 JSON_HEDLEY_GCC_VERSION_CHECK(3,1,0) || \
1595 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1596 JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,11,0) || \
1597 JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
1598 JSON_HEDLEY_IBM_VERSION_CHECK(12,1,0) || \
1599 JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \
1600 (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1601 JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \
1602 (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1603 JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \
1604 (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1605 JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \
1606 (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1607 JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \
1608 JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1609 JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \
1610 JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1611 #define JSON_HEDLEY_MALLOC __attribute__((__malloc__))
1612#elif JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,10,0)
1613 #define JSON_HEDLEY_MALLOC _Pragma("returns_new_memory")
1614#elif \
1615 JSON_HEDLEY_MSVC_VERSION_CHECK(14,0,0) || \
1616 JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0)
1617 #define JSON_HEDLEY_MALLOC __declspec(restrict)
1618#else
1619 #define JSON_HEDLEY_MALLOC
1620#endif
1621
1622#if defined(JSON_HEDLEY_PURE)
1623 #undef JSON_HEDLEY_PURE
1624#endif
1625#if \
1626 JSON_HEDLEY_HAS_ATTRIBUTE(pure) || \
1627 JSON_HEDLEY_GCC_VERSION_CHECK(2,96,0) || \
1628 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1629 JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,11,0) || \
1630 JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
1631 JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) || \
1632 JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \
1633 (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1634 JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \
1635 (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1636 JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \
1637 (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1638 JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \
1639 (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1640 JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \
1641 JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1642 JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \
1643 JSON_HEDLEY_PGI_VERSION_CHECK(17,10,0) || \
1644 JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1645# define JSON_HEDLEY_PURE __attribute__((__pure__))
1646#elif JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,10,0)
1647# define JSON_HEDLEY_PURE _Pragma("does_not_write_global_data")
1648#elif defined(__cplusplus) && \
1649 ( \
1650 JSON_HEDLEY_TI_CL430_VERSION_CHECK(2,0,1) || \
1651 JSON_HEDLEY_TI_CL6X_VERSION_CHECK(4,0,0) || \
1652 JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) \
1653 )
1654# define JSON_HEDLEY_PURE _Pragma("FUNC_IS_PURE;")
1655#else
1656# define JSON_HEDLEY_PURE
1657#endif
1658
1659#if defined(JSON_HEDLEY_CONST)
1660 #undef JSON_HEDLEY_CONST
1661#endif
1662#if \
1663 JSON_HEDLEY_HAS_ATTRIBUTE(const) || \
1664 JSON_HEDLEY_GCC_VERSION_CHECK(2,5,0) || \
1665 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1666 JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,11,0) || \
1667 JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
1668 JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) || \
1669 JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \
1670 (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1671 JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \
1672 (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1673 JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \
1674 (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1675 JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \
1676 (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1677 JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \
1678 JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1679 JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \
1680 JSON_HEDLEY_PGI_VERSION_CHECK(17,10,0) || \
1681 JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1682 #define JSON_HEDLEY_CONST __attribute__((__const__))
1683#elif \
1684 JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,10,0)
1685 #define JSON_HEDLEY_CONST _Pragma("no_side_effect")
1686#else
1687 #define JSON_HEDLEY_CONST JSON_HEDLEY_PURE
1688#endif
1689
1690#if defined(JSON_HEDLEY_RESTRICT)
1691 #undef JSON_HEDLEY_RESTRICT
1692#endif
1693#if defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) && !defined(__cplusplus)
1694 #define JSON_HEDLEY_RESTRICT restrict
1695#elif \
1696 JSON_HEDLEY_GCC_VERSION_CHECK(3,1,0) || \
1697 JSON_HEDLEY_MSVC_VERSION_CHECK(14,0,0) || \
1698 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1699 JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0) || \
1700 JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
1701 JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) || \
1702 JSON_HEDLEY_PGI_VERSION_CHECK(17,10,0) || \
1703 JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \
1704 JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,2,4) || \
1705 JSON_HEDLEY_TI_CL6X_VERSION_CHECK(8,1,0) || \
1706 JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1707 (JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,14,0) && defined(__cplusplus)) || \
1708 JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0) || \
1709 defined(__clang__) || \
1710 JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1711 #define JSON_HEDLEY_RESTRICT __restrict
1712#elif JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,3,0) && !defined(__cplusplus)
1713 #define JSON_HEDLEY_RESTRICT _Restrict
1714#else
1715 #define JSON_HEDLEY_RESTRICT
1716#endif
1717
1718#if defined(JSON_HEDLEY_INLINE)
1719 #undef JSON_HEDLEY_INLINE
1720#endif
1721#if \
1722 (defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L)) || \
1723 (defined(__cplusplus) && (__cplusplus >= 199711L))
1724 #define JSON_HEDLEY_INLINE inline
1725#elif \
1726 defined(JSON_HEDLEY_GCC_VERSION) || \
1727 JSON_HEDLEY_ARM_VERSION_CHECK(6,2,0)
1728 #define JSON_HEDLEY_INLINE __inline__
1729#elif \
1730 JSON_HEDLEY_MSVC_VERSION_CHECK(12,0,0) || \
1731 JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0) || \
1732 JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
1733 JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,1,0) || \
1734 JSON_HEDLEY_TI_CL430_VERSION_CHECK(3,1,0) || \
1735 JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,2,0) || \
1736 JSON_HEDLEY_TI_CL6X_VERSION_CHECK(8,0,0) || \
1737 JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1738 JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \
1739 JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1740 #define JSON_HEDLEY_INLINE __inline
1741#else
1742 #define JSON_HEDLEY_INLINE
1743#endif
1744
1745#if defined(JSON_HEDLEY_ALWAYS_INLINE)
1746 #undef JSON_HEDLEY_ALWAYS_INLINE
1747#endif
1748#if \
1749 JSON_HEDLEY_HAS_ATTRIBUTE(always_inline) || \
1750 JSON_HEDLEY_GCC_VERSION_CHECK(4,0,0) || \
1751 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1752 JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,11,0) || \
1753 JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
1754 JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) || \
1755 JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \
1756 (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1757 JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \
1758 (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1759 JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \
1760 (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1761 JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \
1762 (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1763 JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \
1764 JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1765 JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \
1766 JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10) || \
1767 JSON_HEDLEY_IAR_VERSION_CHECK(8,10,0)
1768# define JSON_HEDLEY_ALWAYS_INLINE __attribute__((__always_inline__)) JSON_HEDLEY_INLINE
1769#elif \
1770 JSON_HEDLEY_MSVC_VERSION_CHECK(12,0,0) || \
1771 JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0)
1772# define JSON_HEDLEY_ALWAYS_INLINE __forceinline
1773#elif defined(__cplusplus) && \
1774 ( \
1775 JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \
1776 JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \
1777 JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \
1778 JSON_HEDLEY_TI_CL6X_VERSION_CHECK(6,1,0) || \
1779 JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1780 JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) \
1781 )
1782# define JSON_HEDLEY_ALWAYS_INLINE _Pragma("FUNC_ALWAYS_INLINE;")
1783#elif JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0)
1784# define JSON_HEDLEY_ALWAYS_INLINE _Pragma("inline=forced")
1785#else
1786# define JSON_HEDLEY_ALWAYS_INLINE JSON_HEDLEY_INLINE
1787#endif
1788
1789#if defined(JSON_HEDLEY_NEVER_INLINE)
1790 #undef JSON_HEDLEY_NEVER_INLINE
1791#endif
1792#if \
1793 JSON_HEDLEY_HAS_ATTRIBUTE(noinline) || \
1794 JSON_HEDLEY_GCC_VERSION_CHECK(4,0,0) || \
1795 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1796 JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,11,0) || \
1797 JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
1798 JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) || \
1799 JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \
1800 (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1801 JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \
1802 (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1803 JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \
1804 (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1805 JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \
1806 (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1807 JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \
1808 JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1809 JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \
1810 JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10) || \
1811 JSON_HEDLEY_IAR_VERSION_CHECK(8,10,0)
1812 #define JSON_HEDLEY_NEVER_INLINE __attribute__((__noinline__))
1813#elif \
1814 JSON_HEDLEY_MSVC_VERSION_CHECK(13,10,0) || \
1815 JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0)
1816 #define JSON_HEDLEY_NEVER_INLINE __declspec(noinline)
1817#elif JSON_HEDLEY_PGI_VERSION_CHECK(10,2,0)
1818 #define JSON_HEDLEY_NEVER_INLINE _Pragma("noinline")
1819#elif JSON_HEDLEY_TI_CL6X_VERSION_CHECK(6,0,0) && defined(__cplusplus)
1820 #define JSON_HEDLEY_NEVER_INLINE _Pragma("FUNC_CANNOT_INLINE;")
1821#elif JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0)
1822 #define JSON_HEDLEY_NEVER_INLINE _Pragma("inline=never")
1823#elif JSON_HEDLEY_COMPCERT_VERSION_CHECK(3,2,0)
1824 #define JSON_HEDLEY_NEVER_INLINE __attribute((noinline))
1825#elif JSON_HEDLEY_PELLES_VERSION_CHECK(9,0,0)
1826 #define JSON_HEDLEY_NEVER_INLINE __declspec(noinline)
1827#else
1828 #define JSON_HEDLEY_NEVER_INLINE
1829#endif
1830
1831#if defined(JSON_HEDLEY_PRIVATE)
1832 #undef JSON_HEDLEY_PRIVATE
1833#endif
1834#if defined(JSON_HEDLEY_PUBLIC)
1835 #undef JSON_HEDLEY_PUBLIC
1836#endif
1837#if defined(JSON_HEDLEY_IMPORT)
1838 #undef JSON_HEDLEY_IMPORT
1839#endif
1840#if defined(_WIN32) || defined(__CYGWIN__)
1841# define JSON_HEDLEY_PRIVATE
1842# define JSON_HEDLEY_PUBLIC __declspec(dllexport)
1843# define JSON_HEDLEY_IMPORT __declspec(dllimport)
1844#else
1845# if \
1846 JSON_HEDLEY_HAS_ATTRIBUTE(visibility) || \
1847 JSON_HEDLEY_GCC_VERSION_CHECK(3,3,0) || \
1848 JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,11,0) || \
1849 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1850 JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
1851 JSON_HEDLEY_IBM_VERSION_CHECK(13,1,0) || \
1852 ( \
1853 defined(__TI_EABI__) && \
1854 ( \
1855 (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1856 JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) \
1857 ) \
1858 ) || \
1859 JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1860# define JSON_HEDLEY_PRIVATE __attribute__((__visibility__("hidden")))
1861# define JSON_HEDLEY_PUBLIC __attribute__((__visibility__("default")))
1862# else
1863# define JSON_HEDLEY_PRIVATE
1864# define JSON_HEDLEY_PUBLIC
1865# endif
1866# define JSON_HEDLEY_IMPORT extern
1867#endif
1868
1869#if defined(JSON_HEDLEY_NO_THROW)
1870 #undef JSON_HEDLEY_NO_THROW
1871#endif
1872#if \
1873 JSON_HEDLEY_HAS_ATTRIBUTE(nothrow) || \
1874 JSON_HEDLEY_GCC_VERSION_CHECK(3,3,0) || \
1875 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1876 JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1877 #define JSON_HEDLEY_NO_THROW __attribute__((__nothrow__))
1878#elif \
1879 JSON_HEDLEY_MSVC_VERSION_CHECK(13,1,0) || \
1880 JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0) || \
1881 JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0)
1882 #define JSON_HEDLEY_NO_THROW __declspec(nothrow)
1883#else
1884 #define JSON_HEDLEY_NO_THROW
1885#endif
1886
1887#if defined(JSON_HEDLEY_FALL_THROUGH)
1888 #undef JSON_HEDLEY_FALL_THROUGH
1889#endif
1890#if \
1891 JSON_HEDLEY_HAS_ATTRIBUTE(fallthrough) || \
1892 JSON_HEDLEY_GCC_VERSION_CHECK(7,0,0) || \
1893 JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1894 #define JSON_HEDLEY_FALL_THROUGH __attribute__((__fallthrough__))
1895#elif JSON_HEDLEY_HAS_CPP_ATTRIBUTE_NS(clang,fallthrough)
1896 #define JSON_HEDLEY_FALL_THROUGH JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[clang::fallthrough]])
1897#elif JSON_HEDLEY_HAS_CPP_ATTRIBUTE(fallthrough)
1898 #define JSON_HEDLEY_FALL_THROUGH JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[fallthrough]])
1899#elif defined(__fallthrough) /* SAL */
1900 #define JSON_HEDLEY_FALL_THROUGH __fallthrough
1901#else
1902 #define JSON_HEDLEY_FALL_THROUGH
1903#endif
1904
1905#if defined(JSON_HEDLEY_RETURNS_NON_NULL)
1906 #undef JSON_HEDLEY_RETURNS_NON_NULL
1907#endif
1908#if \
1909 JSON_HEDLEY_HAS_ATTRIBUTE(returns_nonnull) || \
1910 JSON_HEDLEY_GCC_VERSION_CHECK(4,9,0) || \
1911 JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1912 #define JSON_HEDLEY_RETURNS_NON_NULL __attribute__((__returns_nonnull__))
1913#elif defined(_Ret_notnull_) /* SAL */
1914 #define JSON_HEDLEY_RETURNS_NON_NULL _Ret_notnull_
1915#else
1916 #define JSON_HEDLEY_RETURNS_NON_NULL
1917#endif
1918
1919#if defined(JSON_HEDLEY_ARRAY_PARAM)
1920 #undef JSON_HEDLEY_ARRAY_PARAM
1921#endif
1922#if \
1923 defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) && \
1924 !defined(__STDC_NO_VLA__) && \
1925 !defined(__cplusplus) && \
1926 !defined(JSON_HEDLEY_PGI_VERSION) && \
1927 !defined(JSON_HEDLEY_TINYC_VERSION)
1928 #define JSON_HEDLEY_ARRAY_PARAM(name) (name)
1929#else
1930 #define JSON_HEDLEY_ARRAY_PARAM(name)
1931#endif
1932
1933#if defined(JSON_HEDLEY_IS_CONSTANT)
1934 #undef JSON_HEDLEY_IS_CONSTANT
1935#endif
1936#if defined(JSON_HEDLEY_REQUIRE_CONSTEXPR)
1937 #undef JSON_HEDLEY_REQUIRE_CONSTEXPR
1938#endif
1939/* JSON_HEDLEY_IS_CONSTEXPR_ is for
1940 HEDLEY INTERNAL USE ONLY. API subject to change without notice. */
1941#if defined(JSON_HEDLEY_IS_CONSTEXPR_)
1942 #undef JSON_HEDLEY_IS_CONSTEXPR_
1943#endif
1944#if \
1945 JSON_HEDLEY_HAS_BUILTIN(__builtin_constant_p) || \
1946 JSON_HEDLEY_GCC_VERSION_CHECK(3,4,0) || \
1947 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1948 JSON_HEDLEY_TINYC_VERSION_CHECK(0,9,19) || \
1949 JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
1950 JSON_HEDLEY_IBM_VERSION_CHECK(13,1,0) || \
1951 JSON_HEDLEY_TI_CL6X_VERSION_CHECK(6,1,0) || \
1952 (JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,10,0) && !defined(__cplusplus)) || \
1953 JSON_HEDLEY_CRAY_VERSION_CHECK(8,1,0) || \
1954 JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1955 #define JSON_HEDLEY_IS_CONSTANT(expr) __builtin_constant_p(expr)
1956#endif
1957#if !defined(__cplusplus)
1958# if \
1959 JSON_HEDLEY_HAS_BUILTIN(__builtin_types_compatible_p) || \
1960 JSON_HEDLEY_GCC_VERSION_CHECK(3,4,0) || \
1961 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1962 JSON_HEDLEY_IBM_VERSION_CHECK(13,1,0) || \
1963 JSON_HEDLEY_CRAY_VERSION_CHECK(8,1,0) || \
1964 JSON_HEDLEY_ARM_VERSION_CHECK(5,4,0) || \
1965 JSON_HEDLEY_TINYC_VERSION_CHECK(0,9,24)
1966#if defined(__INTPTR_TYPE__)
1967 #define JSON_HEDLEY_IS_CONSTEXPR_(expr) __builtin_types_compatible_p(__typeof__((1 ? (void*) ((__INTPTR_TYPE__) ((expr) * 0)) : (int*) 0)), int*)
1968#else
1969 #include <stdint.h>
1970 #define JSON_HEDLEY_IS_CONSTEXPR_(expr) __builtin_types_compatible_p(__typeof__((1 ? (void*) ((intptr_t) ((expr) * 0)) : (int*) 0)), int*)
1971#endif
1972# elif \
1973 ( \
1974 defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 201112L) && \
1975 !defined(JSON_HEDLEY_SUNPRO_VERSION) && \
1976 !defined(JSON_HEDLEY_PGI_VERSION) && \
1977 !defined(JSON_HEDLEY_IAR_VERSION)) || \
1978 (JSON_HEDLEY_HAS_EXTENSION(c_generic_selections) && !defined(JSON_HEDLEY_IAR_VERSION)) || \
1979 JSON_HEDLEY_GCC_VERSION_CHECK(4,9,0) || \
1980 JSON_HEDLEY_INTEL_VERSION_CHECK(17,0,0) || \
1981 JSON_HEDLEY_IBM_VERSION_CHECK(12,1,0) || \
1982 JSON_HEDLEY_ARM_VERSION_CHECK(5,3,0)
1983#if defined(__INTPTR_TYPE__)
1984 #define JSON_HEDLEY_IS_CONSTEXPR_(expr) _Generic((1 ? (void*) ((__INTPTR_TYPE__) ((expr) * 0)) : (int*) 0), int*: 1, void*: 0)
1985#else
1986 #include <stdint.h>
1987 #define JSON_HEDLEY_IS_CONSTEXPR_(expr) _Generic((1 ? (void*) ((intptr_t) * 0) : (int*) 0), int*: 1, void*: 0)
1988#endif
1989# elif \
1990 defined(JSON_HEDLEY_GCC_VERSION) || \
1991 defined(JSON_HEDLEY_INTEL_VERSION) || \
1992 defined(JSON_HEDLEY_TINYC_VERSION) || \
1993 defined(JSON_HEDLEY_TI_ARMCL_VERSION) || \
1994 JSON_HEDLEY_TI_CL430_VERSION_CHECK(18,12,0) || \
1995 defined(JSON_HEDLEY_TI_CL2000_VERSION) || \
1996 defined(JSON_HEDLEY_TI_CL6X_VERSION) || \
1997 defined(JSON_HEDLEY_TI_CL7X_VERSION) || \
1998 defined(JSON_HEDLEY_TI_CLPRU_VERSION) || \
1999 defined(__clang__)
2000# define JSON_HEDLEY_IS_CONSTEXPR_(expr) ( \
2001 sizeof(void) != \
2002 sizeof(*( \
2003 1 ? \
2004 ((void*) ((expr) * 0L) ) : \
2005((struct { char v[sizeof(void) * 2]; } *) 1) \
2006 ) \
2007 ) \
2008 )
2009# endif
2010#endif
2011#if defined(JSON_HEDLEY_IS_CONSTEXPR_)
2012 #if !defined(JSON_HEDLEY_IS_CONSTANT)
2013 #define JSON_HEDLEY_IS_CONSTANT(expr) JSON_HEDLEY_IS_CONSTEXPR_(expr)
2014 #endif
2015 #define JSON_HEDLEY_REQUIRE_CONSTEXPR(expr) (JSON_HEDLEY_IS_CONSTEXPR_(expr) ? (expr) : (-1))
2016#else
2017 #if !defined(JSON_HEDLEY_IS_CONSTANT)
2018 #define JSON_HEDLEY_IS_CONSTANT(expr) (0)
2019 #endif
2020 #define JSON_HEDLEY_REQUIRE_CONSTEXPR(expr) (expr)
2021#endif
2022
2023#if defined(JSON_HEDLEY_BEGIN_C_DECLS)
2024 #undef JSON_HEDLEY_BEGIN_C_DECLS
2025#endif
2026#if defined(JSON_HEDLEY_END_C_DECLS)
2027 #undef JSON_HEDLEY_END_C_DECLS
2028#endif
2029#if defined(JSON_HEDLEY_C_DECL)
2030 #undef JSON_HEDLEY_C_DECL
2031#endif
2032#if defined(__cplusplus)
2033 #define JSON_HEDLEY_BEGIN_C_DECLS extern "C" {
2034 #define JSON_HEDLEY_END_C_DECLS }
2035 #define JSON_HEDLEY_C_DECL extern "C"
2036#else
2037 #define JSON_HEDLEY_BEGIN_C_DECLS
2038 #define JSON_HEDLEY_END_C_DECLS
2039 #define JSON_HEDLEY_C_DECL
2040#endif
2041
2042#if defined(JSON_HEDLEY_STATIC_ASSERT)
2043 #undef JSON_HEDLEY_STATIC_ASSERT
2044#endif
2045#if \
2046 !defined(__cplusplus) && ( \
2047 (defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 201112L)) || \
2048 (JSON_HEDLEY_HAS_FEATURE(c_static_assert) && !defined(JSON_HEDLEY_INTEL_CL_VERSION)) || \
2049 JSON_HEDLEY_GCC_VERSION_CHECK(6,0,0) || \
2050 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
2051 defined(_Static_assert) \
2052 )
2053# define JSON_HEDLEY_STATIC_ASSERT(expr, message) _Static_assert(expr, message)
2054#elif \
2055 (defined(__cplusplus) && (__cplusplus >= 201103L)) || \
2056 JSON_HEDLEY_MSVC_VERSION_CHECK(16,0,0) || \
2057 JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0)
2058# define JSON_HEDLEY_STATIC_ASSERT(expr, message) JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_(static_assert(expr, message))
2059#else
2060# define JSON_HEDLEY_STATIC_ASSERT(expr, message)
2061#endif
2062
2063#if defined(JSON_HEDLEY_NULL)
2064 #undef JSON_HEDLEY_NULL
2065#endif
2066#if defined(__cplusplus)
2067 #if __cplusplus >= 201103L
2068 #define JSON_HEDLEY_NULL JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_(nullptr)
2069 #elif defined(NULL)
2070 #define JSON_HEDLEY_NULL NULL
2071 #else
2072 #define JSON_HEDLEY_NULL JSON_HEDLEY_STATIC_CAST(void*, 0)
2073 #endif
2074#elif defined(NULL)
2075 #define JSON_HEDLEY_NULL NULL
2076#else
2077 #define JSON_HEDLEY_NULL ((void*) 0)
2078#endif
2079
2080#if defined(JSON_HEDLEY_MESSAGE)
2081 #undef JSON_HEDLEY_MESSAGE
2082#endif
2083#if JSON_HEDLEY_HAS_WARNING("-Wunknown-pragmas")
2084# define JSON_HEDLEY_MESSAGE(msg) \
2085 JSON_HEDLEY_DIAGNOSTIC_PUSH \
2086 JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS \
2087 JSON_HEDLEY_PRAGMA(message msg) \
2088 JSON_HEDLEY_DIAGNOSTIC_POP
2089#elif \
2090 JSON_HEDLEY_GCC_VERSION_CHECK(4,4,0) || \
2091 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0)
2092# define JSON_HEDLEY_MESSAGE(msg) JSON_HEDLEY_PRAGMA(message msg)
2093#elif JSON_HEDLEY_CRAY_VERSION_CHECK(5,0,0)
2094# define JSON_HEDLEY_MESSAGE(msg) JSON_HEDLEY_PRAGMA(_CRI message msg)
2095#elif JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0)
2096# define JSON_HEDLEY_MESSAGE(msg) JSON_HEDLEY_PRAGMA(message(msg))
2097#elif JSON_HEDLEY_PELLES_VERSION_CHECK(2,0,0)
2098# define JSON_HEDLEY_MESSAGE(msg) JSON_HEDLEY_PRAGMA(message(msg))
2099#else
2100# define JSON_HEDLEY_MESSAGE(msg)
2101#endif
2102
2103#if defined(JSON_HEDLEY_WARNING)
2104 #undef JSON_HEDLEY_WARNING
2105#endif
2106#if JSON_HEDLEY_HAS_WARNING("-Wunknown-pragmas")
2107# define JSON_HEDLEY_WARNING(msg) \
2108 JSON_HEDLEY_DIAGNOSTIC_PUSH \
2109 JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS \
2110 JSON_HEDLEY_PRAGMA(clang warning msg) \
2111 JSON_HEDLEY_DIAGNOSTIC_POP
2112#elif \
2113 JSON_HEDLEY_GCC_VERSION_CHECK(4,8,0) || \
2114 JSON_HEDLEY_PGI_VERSION_CHECK(18,4,0) || \
2115 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0)
2116# define JSON_HEDLEY_WARNING(msg) JSON_HEDLEY_PRAGMA(GCC warning msg)
2117#elif \
2118 JSON_HEDLEY_MSVC_VERSION_CHECK(15,0,0) || \
2119 JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0)
2120# define JSON_HEDLEY_WARNING(msg) JSON_HEDLEY_PRAGMA(message(msg))
2121#else
2122# define JSON_HEDLEY_WARNING(msg) JSON_HEDLEY_MESSAGE(msg)
2123#endif
2124
2125#if defined(JSON_HEDLEY_REQUIRE)
2126 #undef JSON_HEDLEY_REQUIRE
2127#endif
2128#if defined(JSON_HEDLEY_REQUIRE_MSG)
2129 #undef JSON_HEDLEY_REQUIRE_MSG
2130#endif
2131#if JSON_HEDLEY_HAS_ATTRIBUTE(diagnose_if)
2132# if JSON_HEDLEY_HAS_WARNING("-Wgcc-compat")
2133# define JSON_HEDLEY_REQUIRE(expr) \
2134 JSON_HEDLEY_DIAGNOSTIC_PUSH \
2135 _Pragma("clang diagnostic ignored \"-Wgcc-compat\"") \
2136 __attribute__((diagnose_if(!(expr), #expr, "error"))) \
2137 JSON_HEDLEY_DIAGNOSTIC_POP
2138# define JSON_HEDLEY_REQUIRE_MSG(expr,msg) \
2139 JSON_HEDLEY_DIAGNOSTIC_PUSH \
2140 _Pragma("clang diagnostic ignored \"-Wgcc-compat\"") \
2141 __attribute__((diagnose_if(!(expr), msg, "error"))) \
2142 JSON_HEDLEY_DIAGNOSTIC_POP
2143# else
2144# define JSON_HEDLEY_REQUIRE(expr) __attribute__((diagnose_if(!(expr), #expr, "error")))
2145# define JSON_HEDLEY_REQUIRE_MSG(expr,msg) __attribute__((diagnose_if(!(expr), msg, "error")))
2146# endif
2147#else
2148# define JSON_HEDLEY_REQUIRE(expr)
2149# define JSON_HEDLEY_REQUIRE_MSG(expr,msg)
2150#endif
2151
2152#if defined(JSON_HEDLEY_FLAGS)
2153 #undef JSON_HEDLEY_FLAGS
2154#endif
2155#if JSON_HEDLEY_HAS_ATTRIBUTE(flag_enum) && (!defined(__cplusplus) || JSON_HEDLEY_HAS_WARNING("-Wbitfield-enum-conversion"))
2156 #define JSON_HEDLEY_FLAGS __attribute__((__flag_enum__))
2157#else
2158 #define JSON_HEDLEY_FLAGS
2159#endif
2160
2161#if defined(JSON_HEDLEY_FLAGS_CAST)
2162 #undef JSON_HEDLEY_FLAGS_CAST
2163#endif
2164#if JSON_HEDLEY_INTEL_VERSION_CHECK(19,0,0)
2165# define JSON_HEDLEY_FLAGS_CAST(T, expr) (__extension__ ({ \
2166 JSON_HEDLEY_DIAGNOSTIC_PUSH \
2167 _Pragma("warning(disable:188)") \
2168 ((T) (expr)); \
2169 JSON_HEDLEY_DIAGNOSTIC_POP \
2170 }))
2171#else
2172# define JSON_HEDLEY_FLAGS_CAST(T, expr) JSON_HEDLEY_STATIC_CAST(T, expr)
2173#endif
2174
2175#if defined(JSON_HEDLEY_EMPTY_BASES)
2176 #undef JSON_HEDLEY_EMPTY_BASES
2177#endif
2178#if \
2179 (JSON_HEDLEY_MSVC_VERSION_CHECK(19,0,23918) && !JSON_HEDLEY_MSVC_VERSION_CHECK(20,0,0)) || \
2180 JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0)
2181 #define JSON_HEDLEY_EMPTY_BASES __declspec(empty_bases)
2182#else
2183 #define JSON_HEDLEY_EMPTY_BASES
2184#endif
2185
2186/* Remaining macros are deprecated. */
2187
2188#if defined(JSON_HEDLEY_GCC_NOT_CLANG_VERSION_CHECK)
2189 #undef JSON_HEDLEY_GCC_NOT_CLANG_VERSION_CHECK
2190#endif
2191#if defined(__clang__)
2192 #define JSON_HEDLEY_GCC_NOT_CLANG_VERSION_CHECK(major,minor,patch) (0)
2193#else
2194 #define JSON_HEDLEY_GCC_NOT_CLANG_VERSION_CHECK(major,minor,patch) JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch)
2195#endif
2196
2197#if defined(JSON_HEDLEY_CLANG_HAS_ATTRIBUTE)
2198 #undef JSON_HEDLEY_CLANG_HAS_ATTRIBUTE
2199#endif
2200#define JSON_HEDLEY_CLANG_HAS_ATTRIBUTE(attribute) JSON_HEDLEY_HAS_ATTRIBUTE(attribute)
2201
2202#if defined(JSON_HEDLEY_CLANG_HAS_CPP_ATTRIBUTE)
2203 #undef JSON_HEDLEY_CLANG_HAS_CPP_ATTRIBUTE
2204#endif
2205#define JSON_HEDLEY_CLANG_HAS_CPP_ATTRIBUTE(attribute) JSON_HEDLEY_HAS_CPP_ATTRIBUTE(attribute)
2206
2207#if defined(JSON_HEDLEY_CLANG_HAS_BUILTIN)
2208 #undef JSON_HEDLEY_CLANG_HAS_BUILTIN
2209#endif
2210#define JSON_HEDLEY_CLANG_HAS_BUILTIN(builtin) JSON_HEDLEY_HAS_BUILTIN(builtin)
2211
2212#if defined(JSON_HEDLEY_CLANG_HAS_FEATURE)
2213 #undef JSON_HEDLEY_CLANG_HAS_FEATURE
2214#endif
2215#define JSON_HEDLEY_CLANG_HAS_FEATURE(feature) JSON_HEDLEY_HAS_FEATURE(feature)
2216
2217#if defined(JSON_HEDLEY_CLANG_HAS_EXTENSION)
2218 #undef JSON_HEDLEY_CLANG_HAS_EXTENSION
2219#endif
2220#define JSON_HEDLEY_CLANG_HAS_EXTENSION(extension) JSON_HEDLEY_HAS_EXTENSION(extension)
2221
2222#if defined(JSON_HEDLEY_CLANG_HAS_DECLSPEC_DECLSPEC_ATTRIBUTE)
2223 #undef JSON_HEDLEY_CLANG_HAS_DECLSPEC_DECLSPEC_ATTRIBUTE
2224#endif
2225#define JSON_HEDLEY_CLANG_HAS_DECLSPEC_ATTRIBUTE(attribute) JSON_HEDLEY_HAS_DECLSPEC_ATTRIBUTE(attribute)
2226
2227#if defined(JSON_HEDLEY_CLANG_HAS_WARNING)
2228 #undef JSON_HEDLEY_CLANG_HAS_WARNING
2229#endif
2230#define JSON_HEDLEY_CLANG_HAS_WARNING(warning) JSON_HEDLEY_HAS_WARNING(warning)
2231
2232#endif /* !defined(JSON_HEDLEY_VERSION) || (JSON_HEDLEY_VERSION < X) */
2233
2234// #include <nlohmann/detail/meta/detected.hpp>
2235
2236
2237#include <type_traits>
2238
2239// #include <nlohmann/detail/meta/void_t.hpp>
2240
2241
2242namespace nlohmann
2243{
2244namespace detail
2245{
2246template<typename ...Ts> struct make_void
2247{
2248 using type = void;
2249};
2250template<typename ...Ts> using void_t = typename make_void<Ts...>::type;
2251} // namespace detail
2252} // namespace nlohmann
2253
2254
2255// https://en.cppreference.com/w/cpp/experimental/is_detected
2256namespace nlohmann
2257{
2258namespace detail
2259{
2261{
2262 nonesuch() = delete;
2263 ~nonesuch() = delete;
2264 nonesuch(nonesuch const&) = delete;
2265 nonesuch(nonesuch const&&) = delete;
2266 void operator=(nonesuch const&) = delete;
2267 void operator=(nonesuch&&) = delete;
2268};
2269
2270template<class Default,
2271 class AlwaysVoid,
2272 template<class...> class Op,
2273 class... Args>
2275{
2276 using value_t = std::false_type;
2277 using type = Default;
2278};
2279
2280template<class Default, template<class...> class Op, class... Args>
2281struct detector<Default, void_t<Op<Args...>>, Op, Args...>
2282{
2283 using value_t = std::true_type;
2284 using type = Op<Args...>;
2285};
2286
2287template<template<class...> class Op, class... Args>
2288using is_detected = typename detector<nonesuch, void, Op, Args...>::value_t;
2289
2290template<template<class...> class Op, class... Args>
2291struct is_detected_lazy : is_detected<Op, Args...> { };
2292
2293template<template<class...> class Op, class... Args>
2294using detected_t = typename detector<nonesuch, void, Op, Args...>::type;
2295
2296template<class Default, template<class...> class Op, class... Args>
2297using detected_or = detector<Default, void, Op, Args...>;
2298
2299template<class Default, template<class...> class Op, class... Args>
2300using detected_or_t = typename detected_or<Default, Op, Args...>::type;
2301
2302template<class Expected, template<class...> class Op, class... Args>
2303using is_detected_exact = std::is_same<Expected, detected_t<Op, Args...>>;
2304
2305template<class To, template<class...> class Op, class... Args>
2307 std::is_convertible<detected_t<Op, Args...>, To>;
2308} // namespace detail
2309} // namespace nlohmann
2310
2311
2312// This file contains all internal macro definitions
2313// You MUST include macro_unscope.hpp at the end of json.hpp to undef all of them
2314
2315// exclude unsupported compilers
2316#if !defined(JSON_SKIP_UNSUPPORTED_COMPILER_CHECK)
2317 #if defined(__clang__)
2318 #if (__clang_major__ * 10000 + __clang_minor__ * 100 + __clang_patchlevel__) < 30400
2319 #error "unsupported Clang version - see https://github.com/nlohmann/json#supported-compilers"
2320 #endif
2321 #elif defined(__GNUC__) && !(defined(__ICC) || defined(__INTEL_COMPILER))
2322 #if (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__) < 40800
2323 #error "unsupported GCC version - see https://github.com/nlohmann/json#supported-compilers"
2324 #endif
2325 #endif
2326#endif
2327
2328// C++ language standard detection
2329// if the user manually specified the used c++ version this is skipped
2330#if !defined(JSON_HAS_CPP_20) && !defined(JSON_HAS_CPP_17) && !defined(JSON_HAS_CPP_14) && !defined(JSON_HAS_CPP_11)
2331 #if (defined(__cplusplus) && __cplusplus >= 202002L) || (defined(_MSVC_LANG) && _MSVC_LANG >= 202002L)
2332 #define JSON_HAS_CPP_20
2333 #define JSON_HAS_CPP_17
2334 #define JSON_HAS_CPP_14
2335 #elif (defined(__cplusplus) && __cplusplus >= 201703L) || (defined(_HAS_CXX17) && _HAS_CXX17 == 1) // fix for issue #464
2336 #define JSON_HAS_CPP_17
2337 #define JSON_HAS_CPP_14
2338 #elif (defined(__cplusplus) && __cplusplus >= 201402L) || (defined(_HAS_CXX14) && _HAS_CXX14 == 1)
2339 #define JSON_HAS_CPP_14
2340 #endif
2341 // the cpp 11 flag is always specified because it is the minimal required version
2342 #define JSON_HAS_CPP_11
2343#endif
2344
2345#if !defined(JSON_HAS_FILESYSTEM) && !defined(JSON_HAS_EXPERIMENTAL_FILESYSTEM)
2346 #ifdef JSON_HAS_CPP_17
2347 #if defined(__cpp_lib_filesystem)
2348 #define JSON_HAS_FILESYSTEM 1
2349 #elif defined(__cpp_lib_experimental_filesystem)
2350 #define JSON_HAS_EXPERIMENTAL_FILESYSTEM 1
2351 #elif !defined(__has_include)
2352 #define JSON_HAS_EXPERIMENTAL_FILESYSTEM 1
2353 #elif __has_include(<filesystem>)
2354 #define JSON_HAS_FILESYSTEM 1
2355 #elif __has_include(<experimental/filesystem>)
2356 #define JSON_HAS_EXPERIMENTAL_FILESYSTEM 1
2357 #endif
2358
2359 // std::filesystem does not work on MinGW GCC 8: https://sourceforge.net/p/mingw-w64/bugs/737/
2360 #if defined(__MINGW32__) && defined(__GNUC__) && __GNUC__ == 8
2361 #undef JSON_HAS_FILESYSTEM
2362 #undef JSON_HAS_EXPERIMENTAL_FILESYSTEM
2363 #endif
2364
2365 // no filesystem support before GCC 8: https://en.cppreference.com/w/cpp/compiler_support
2366 #if defined(__GNUC__) && !defined(__clang__) && __GNUC__ < 8
2367 #undef JSON_HAS_FILESYSTEM
2368 #undef JSON_HAS_EXPERIMENTAL_FILESYSTEM
2369 #endif
2370
2371 // no filesystem support before Clang 7: https://en.cppreference.com/w/cpp/compiler_support
2372 #if defined(__clang_major__) && __clang_major__ < 7
2373 #undef JSON_HAS_FILESYSTEM
2374 #undef JSON_HAS_EXPERIMENTAL_FILESYSTEM
2375 #endif
2376
2377 // no filesystem support before MSVC 19.14: https://en.cppreference.com/w/cpp/compiler_support
2378 #if defined(_MSC_VER) && _MSC_VER < 1914
2379 #undef JSON_HAS_FILESYSTEM
2380 #undef JSON_HAS_EXPERIMENTAL_FILESYSTEM
2381 #endif
2382
2383 // no filesystem support before iOS 13
2384 #if defined(__IPHONE_OS_VERSION_MIN_REQUIRED) && __IPHONE_OS_VERSION_MIN_REQUIRED < 130000
2385 #undef JSON_HAS_FILESYSTEM
2386 #undef JSON_HAS_EXPERIMENTAL_FILESYSTEM
2387 #endif
2388
2389 // no filesystem support before macOS Catalina
2390 #if defined(__MAC_OS_X_VERSION_MIN_REQUIRED) && __MAC_OS_X_VERSION_MIN_REQUIRED < 101500
2391 #undef JSON_HAS_FILESYSTEM
2392 #undef JSON_HAS_EXPERIMENTAL_FILESYSTEM
2393 #endif
2394 #endif
2395#endif
2396
2397#ifndef JSON_HAS_EXPERIMENTAL_FILESYSTEM
2398 #define JSON_HAS_EXPERIMENTAL_FILESYSTEM 0
2399#endif
2400
2401#ifndef JSON_HAS_FILESYSTEM
2402 #define JSON_HAS_FILESYSTEM 0
2403#endif
2404
2405#ifndef JSON_HAS_THREE_WAY_COMPARISON
2406 #if defined(__cpp_lib_three_way_comparison) && __cpp_lib_three_way_comparison >= 201907L \
2407 && defined(__cpp_impl_three_way_comparison)&& __cpp_impl_three_way_comparison >= 201907L
2408 #define JSON_HAS_THREE_WAY_COMPARISON 1
2409 #else
2410 #define JSON_HAS_THREE_WAY_COMPARISON 0
2411 #endif
2412#endif
2413
2414#if JSON_HEDLEY_HAS_ATTRIBUTE(no_unique_address)
2415 #define JSON_NO_UNIQUE_ADDRESS [[no_unique_address]]
2416#else
2417 #define JSON_NO_UNIQUE_ADDRESS
2418#endif
2419
2420// disable documentation warnings on clang
2421#if defined(__clang__)
2422 #pragma clang diagnostic push
2423 #pragma clang diagnostic ignored "-Wdocumentation"
2424 #pragma clang diagnostic ignored "-Wdocumentation-unknown-command"
2425#endif
2426
2427// allow disabling exceptions
2428#if (defined(__cpp_exceptions) || defined(__EXCEPTIONS) || defined(_CPPUNWIND)) && !defined(JSON_NOEXCEPTION)
2429 #define JSON_THROW(exception) throw exception
2430 #define JSON_TRY try
2431 #define JSON_CATCH(exception) catch(exception)
2432 #define JSON_INTERNAL_CATCH(exception) catch(exception)
2433#else
2434 #include <cstdlib>
2435 #define JSON_THROW(exception) std::abort()
2436 #define JSON_TRY if(true)
2437 #define JSON_CATCH(exception) if(false)
2438 #define JSON_INTERNAL_CATCH(exception) if(false)
2439#endif
2440
2441// override exception macros
2442#if defined(JSON_THROW_USER)
2443 #undef JSON_THROW
2444 #define JSON_THROW JSON_THROW_USER
2445#endif
2446#if defined(JSON_TRY_USER)
2447 #undef JSON_TRY
2448 #define JSON_TRY JSON_TRY_USER
2449#endif
2450#if defined(JSON_CATCH_USER)
2451 #undef JSON_CATCH
2452 #define JSON_CATCH JSON_CATCH_USER
2453 #undef JSON_INTERNAL_CATCH
2454 #define JSON_INTERNAL_CATCH JSON_CATCH_USER
2455#endif
2456#if defined(JSON_INTERNAL_CATCH_USER)
2457 #undef JSON_INTERNAL_CATCH
2458 #define JSON_INTERNAL_CATCH JSON_INTERNAL_CATCH_USER
2459#endif
2460
2461// allow overriding assert
2462#if !defined(JSON_ASSERT)
2463 #include <cassert> // assert
2464 #define JSON_ASSERT(x) assert(x)
2465#endif
2466
2467// allow to access some private functions (needed by the test suite)
2468#if defined(JSON_TESTS_PRIVATE)
2469 #define JSON_PRIVATE_UNLESS_TESTED public
2470#else
2471 #define JSON_PRIVATE_UNLESS_TESTED private
2472#endif
2473
2479#define NLOHMANN_JSON_SERIALIZE_ENUM(ENUM_TYPE, ...) \
2480 template<typename BasicJsonType> \
2481 inline void to_json(BasicJsonType& j, const ENUM_TYPE& e) \
2482 { \
2483 static_assert(std::is_enum<ENUM_TYPE>::value, #ENUM_TYPE " must be an enum!"); \
2484 static const std::pair<ENUM_TYPE, BasicJsonType> m[] = __VA_ARGS__; \
2485 auto it = std::find_if(std::begin(m), std::end(m), \
2486 [e](const std::pair<ENUM_TYPE, BasicJsonType>& ej_pair) -> bool \
2487 { \
2488 return ej_pair.first == e; \
2489 }); \
2490 j = ((it != std::end(m)) ? it : std::begin(m))->second; \
2491 } \
2492 template<typename BasicJsonType> \
2493 inline void from_json(const BasicJsonType& j, ENUM_TYPE& e) \
2494 { \
2495 static_assert(std::is_enum<ENUM_TYPE>::value, #ENUM_TYPE " must be an enum!"); \
2496 static const std::pair<ENUM_TYPE, BasicJsonType> m[] = __VA_ARGS__; \
2497 auto it = std::find_if(std::begin(m), std::end(m), \
2498 [&j](const std::pair<ENUM_TYPE, BasicJsonType>& ej_pair) -> bool \
2499 { \
2500 return ej_pair.second == j; \
2501 }); \
2502 e = ((it != std::end(m)) ? it : std::begin(m))->first; \
2503 }
2504
2505// Ugly macros to avoid uglier copy-paste when specializing basic_json. They
2506// may be removed in the future once the class is split.
2507
2508#define NLOHMANN_BASIC_JSON_TPL_DECLARATION \
2509 template<template<typename, typename, typename...> class ObjectType, \
2510 template<typename, typename...> class ArrayType, \
2511 class StringType, class BooleanType, class NumberIntegerType, \
2512 class NumberUnsignedType, class NumberFloatType, \
2513 template<typename> class AllocatorType, \
2514 template<typename, typename = void> class JSONSerializer, \
2515 class BinaryType>
2516
2517#define NLOHMANN_BASIC_JSON_TPL \
2518 basic_json<ObjectType, ArrayType, StringType, BooleanType, \
2519 NumberIntegerType, NumberUnsignedType, NumberFloatType, \
2520 AllocatorType, JSONSerializer, BinaryType>
2521
2522// Macros to simplify conversion from/to types
2523
2524#define NLOHMANN_JSON_EXPAND( x ) x
2525#define NLOHMANN_JSON_GET_MACRO(_1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _20, _21, _22, _23, _24, _25, _26, _27, _28, _29, _30, _31, _32, _33, _34, _35, _36, _37, _38, _39, _40, _41, _42, _43, _44, _45, _46, _47, _48, _49, _50, _51, _52, _53, _54, _55, _56, _57, _58, _59, _60, _61, _62, _63, _64, NAME,...) NAME
2526#define NLOHMANN_JSON_PASTE(...) NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_GET_MACRO(__VA_ARGS__, \
2527 NLOHMANN_JSON_PASTE64, \
2528 NLOHMANN_JSON_PASTE63, \
2529 NLOHMANN_JSON_PASTE62, \
2530 NLOHMANN_JSON_PASTE61, \
2531 NLOHMANN_JSON_PASTE60, \
2532 NLOHMANN_JSON_PASTE59, \
2533 NLOHMANN_JSON_PASTE58, \
2534 NLOHMANN_JSON_PASTE57, \
2535 NLOHMANN_JSON_PASTE56, \
2536 NLOHMANN_JSON_PASTE55, \
2537 NLOHMANN_JSON_PASTE54, \
2538 NLOHMANN_JSON_PASTE53, \
2539 NLOHMANN_JSON_PASTE52, \
2540 NLOHMANN_JSON_PASTE51, \
2541 NLOHMANN_JSON_PASTE50, \
2542 NLOHMANN_JSON_PASTE49, \
2543 NLOHMANN_JSON_PASTE48, \
2544 NLOHMANN_JSON_PASTE47, \
2545 NLOHMANN_JSON_PASTE46, \
2546 NLOHMANN_JSON_PASTE45, \
2547 NLOHMANN_JSON_PASTE44, \
2548 NLOHMANN_JSON_PASTE43, \
2549 NLOHMANN_JSON_PASTE42, \
2550 NLOHMANN_JSON_PASTE41, \
2551 NLOHMANN_JSON_PASTE40, \
2552 NLOHMANN_JSON_PASTE39, \
2553 NLOHMANN_JSON_PASTE38, \
2554 NLOHMANN_JSON_PASTE37, \
2555 NLOHMANN_JSON_PASTE36, \
2556 NLOHMANN_JSON_PASTE35, \
2557 NLOHMANN_JSON_PASTE34, \
2558 NLOHMANN_JSON_PASTE33, \
2559 NLOHMANN_JSON_PASTE32, \
2560 NLOHMANN_JSON_PASTE31, \
2561 NLOHMANN_JSON_PASTE30, \
2562 NLOHMANN_JSON_PASTE29, \
2563 NLOHMANN_JSON_PASTE28, \
2564 NLOHMANN_JSON_PASTE27, \
2565 NLOHMANN_JSON_PASTE26, \
2566 NLOHMANN_JSON_PASTE25, \
2567 NLOHMANN_JSON_PASTE24, \
2568 NLOHMANN_JSON_PASTE23, \
2569 NLOHMANN_JSON_PASTE22, \
2570 NLOHMANN_JSON_PASTE21, \
2571 NLOHMANN_JSON_PASTE20, \
2572 NLOHMANN_JSON_PASTE19, \
2573 NLOHMANN_JSON_PASTE18, \
2574 NLOHMANN_JSON_PASTE17, \
2575 NLOHMANN_JSON_PASTE16, \
2576 NLOHMANN_JSON_PASTE15, \
2577 NLOHMANN_JSON_PASTE14, \
2578 NLOHMANN_JSON_PASTE13, \
2579 NLOHMANN_JSON_PASTE12, \
2580 NLOHMANN_JSON_PASTE11, \
2581 NLOHMANN_JSON_PASTE10, \
2582 NLOHMANN_JSON_PASTE9, \
2583 NLOHMANN_JSON_PASTE8, \
2584 NLOHMANN_JSON_PASTE7, \
2585 NLOHMANN_JSON_PASTE6, \
2586 NLOHMANN_JSON_PASTE5, \
2587 NLOHMANN_JSON_PASTE4, \
2588 NLOHMANN_JSON_PASTE3, \
2589 NLOHMANN_JSON_PASTE2, \
2590 NLOHMANN_JSON_PASTE1)(__VA_ARGS__))
2591#define NLOHMANN_JSON_PASTE2(func, v1) func(v1)
2592#define NLOHMANN_JSON_PASTE3(func, v1, v2) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE2(func, v2)
2593#define NLOHMANN_JSON_PASTE4(func, v1, v2, v3) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE3(func, v2, v3)
2594#define NLOHMANN_JSON_PASTE5(func, v1, v2, v3, v4) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE4(func, v2, v3, v4)
2595#define NLOHMANN_JSON_PASTE6(func, v1, v2, v3, v4, v5) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE5(func, v2, v3, v4, v5)
2596#define NLOHMANN_JSON_PASTE7(func, v1, v2, v3, v4, v5, v6) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE6(func, v2, v3, v4, v5, v6)
2597#define NLOHMANN_JSON_PASTE8(func, v1, v2, v3, v4, v5, v6, v7) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE7(func, v2, v3, v4, v5, v6, v7)
2598#define NLOHMANN_JSON_PASTE9(func, v1, v2, v3, v4, v5, v6, v7, v8) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE8(func, v2, v3, v4, v5, v6, v7, v8)
2599#define NLOHMANN_JSON_PASTE10(func, v1, v2, v3, v4, v5, v6, v7, v8, v9) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE9(func, v2, v3, v4, v5, v6, v7, v8, v9)
2600#define NLOHMANN_JSON_PASTE11(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE10(func, v2, v3, v4, v5, v6, v7, v8, v9, v10)
2601#define NLOHMANN_JSON_PASTE12(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE11(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11)
2602#define NLOHMANN_JSON_PASTE13(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE12(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12)
2603#define NLOHMANN_JSON_PASTE14(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE13(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13)
2604#define NLOHMANN_JSON_PASTE15(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE14(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14)
2605#define NLOHMANN_JSON_PASTE16(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE15(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15)
2606#define NLOHMANN_JSON_PASTE17(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE16(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16)
2607#define NLOHMANN_JSON_PASTE18(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE17(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17)
2608#define NLOHMANN_JSON_PASTE19(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE18(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18)
2609#define NLOHMANN_JSON_PASTE20(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE19(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19)
2610#define NLOHMANN_JSON_PASTE21(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE20(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20)
2611#define NLOHMANN_JSON_PASTE22(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE21(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21)
2612#define NLOHMANN_JSON_PASTE23(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE22(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22)
2613#define NLOHMANN_JSON_PASTE24(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE23(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23)
2614#define NLOHMANN_JSON_PASTE25(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE24(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24)
2615#define NLOHMANN_JSON_PASTE26(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE25(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25)
2616#define NLOHMANN_JSON_PASTE27(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE26(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26)
2617#define NLOHMANN_JSON_PASTE28(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE27(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27)
2618#define NLOHMANN_JSON_PASTE29(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE28(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28)
2619#define NLOHMANN_JSON_PASTE30(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE29(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29)
2620#define NLOHMANN_JSON_PASTE31(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE30(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30)
2621#define NLOHMANN_JSON_PASTE32(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE31(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31)
2622#define NLOHMANN_JSON_PASTE33(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE32(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32)
2623#define NLOHMANN_JSON_PASTE34(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE33(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33)
2624#define NLOHMANN_JSON_PASTE35(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE34(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34)
2625#define NLOHMANN_JSON_PASTE36(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE35(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35)
2626#define NLOHMANN_JSON_PASTE37(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE36(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36)
2627#define NLOHMANN_JSON_PASTE38(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE37(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37)
2628#define NLOHMANN_JSON_PASTE39(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE38(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38)
2629#define NLOHMANN_JSON_PASTE40(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE39(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39)
2630#define NLOHMANN_JSON_PASTE41(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE40(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40)
2631#define NLOHMANN_JSON_PASTE42(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE41(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41)
2632#define NLOHMANN_JSON_PASTE43(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE42(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42)
2633#define NLOHMANN_JSON_PASTE44(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE43(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43)
2634#define NLOHMANN_JSON_PASTE45(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE44(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44)
2635#define NLOHMANN_JSON_PASTE46(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE45(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45)
2636#define NLOHMANN_JSON_PASTE47(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE46(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46)
2637#define NLOHMANN_JSON_PASTE48(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE47(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47)
2638#define NLOHMANN_JSON_PASTE49(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE48(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48)
2639#define NLOHMANN_JSON_PASTE50(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE49(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49)
2640#define NLOHMANN_JSON_PASTE51(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE50(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50)
2641#define NLOHMANN_JSON_PASTE52(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE51(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51)
2642#define NLOHMANN_JSON_PASTE53(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE52(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52)
2643#define NLOHMANN_JSON_PASTE54(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE53(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53)
2644#define NLOHMANN_JSON_PASTE55(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE54(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54)
2645#define NLOHMANN_JSON_PASTE56(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE55(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55)
2646#define NLOHMANN_JSON_PASTE57(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE56(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56)
2647#define NLOHMANN_JSON_PASTE58(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE57(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57)
2648#define NLOHMANN_JSON_PASTE59(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE58(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58)
2649#define NLOHMANN_JSON_PASTE60(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58, v59) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE59(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58, v59)
2650#define NLOHMANN_JSON_PASTE61(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58, v59, v60) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE60(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58, v59, v60)
2651#define NLOHMANN_JSON_PASTE62(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58, v59, v60, v61) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE61(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58, v59, v60, v61)
2652#define NLOHMANN_JSON_PASTE63(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58, v59, v60, v61, v62) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE62(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58, v59, v60, v61, v62)
2653#define NLOHMANN_JSON_PASTE64(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58, v59, v60, v61, v62, v63) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE63(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58, v59, v60, v61, v62, v63)
2654
2655#define NLOHMANN_JSON_TO(v1) nlohmann_json_j[#v1] = nlohmann_json_t.v1;
2656#define NLOHMANN_JSON_FROM(v1) nlohmann_json_j.at(#v1).get_to(nlohmann_json_t.v1);
2657#define NLOHMANN_JSON_FROM_WITH_DEFAULT(v1) nlohmann_json_t.v1 = nlohmann_json_j.value(#v1, nlohmann_json_default_obj.v1);
2658
2664#define NLOHMANN_DEFINE_TYPE_INTRUSIVE(Type, ...) \
2665 friend void to_json(nlohmann::json& nlohmann_json_j, const Type& nlohmann_json_t) { NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_TO, __VA_ARGS__)) } \
2666 friend void from_json(const nlohmann::json& nlohmann_json_j, Type& nlohmann_json_t) { NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_FROM, __VA_ARGS__)) }
2667
2668#define NLOHMANN_DEFINE_TYPE_INTRUSIVE_WITH_DEFAULT(Type, ...) \
2669 friend void to_json(nlohmann::json& nlohmann_json_j, const Type& nlohmann_json_t) { NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_TO, __VA_ARGS__)) } \
2670 friend void from_json(const nlohmann::json& nlohmann_json_j, Type& nlohmann_json_t) { Type nlohmann_json_default_obj; NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_FROM_WITH_DEFAULT, __VA_ARGS__)) }
2671
2677#define NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(Type, ...) \
2678 inline void to_json(nlohmann::json& nlohmann_json_j, const Type& nlohmann_json_t) { NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_TO, __VA_ARGS__)) } \
2679 inline void from_json(const nlohmann::json& nlohmann_json_j, Type& nlohmann_json_t) { NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_FROM, __VA_ARGS__)) }
2680
2681#define NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE_WITH_DEFAULT(Type, ...) \
2682 inline void to_json(nlohmann::json& nlohmann_json_j, const Type& nlohmann_json_t) { NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_TO, __VA_ARGS__)) } \
2683 inline void from_json(const nlohmann::json& nlohmann_json_j, Type& nlohmann_json_t) { Type nlohmann_json_default_obj; NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_FROM_WITH_DEFAULT, __VA_ARGS__)) }
2684
2685
2686// inspired from https://stackoverflow.com/a/26745591
2687// allows to call any std function as if (e.g. with begin):
2688// using std::begin; begin(x);
2689//
2690// it allows using the detected idiom to retrieve the return type
2691// of such an expression
2692#define NLOHMANN_CAN_CALL_STD_FUNC_IMPL(std_name) \
2693 namespace detail { \
2694 using std::std_name; \
2695 \
2696 template<typename... T> \
2697 using result_of_##std_name = decltype(std_name(std::declval<T>()...)); \
2698 } \
2699 \
2700 namespace detail2 { \
2701 struct std_name##_tag \
2702 { \
2703 }; \
2704 \
2705 template<typename... T> \
2706 std_name##_tag std_name(T&&...); \
2707 \
2708 template<typename... T> \
2709 using result_of_##std_name = decltype(std_name(std::declval<T>()...)); \
2710 \
2711 template<typename... T> \
2712 struct would_call_std_##std_name \
2713 { \
2714 static constexpr auto const value = ::nlohmann::detail:: \
2715 is_detected_exact<std_name##_tag, result_of_##std_name, T...>::value; \
2716 }; \
2717 } /* namespace detail2 */ \
2718 \
2719 template<typename... T> \
2720 struct would_call_std_##std_name : detail2::would_call_std_##std_name<T...> \
2721 { \
2722 }
2723
2724#ifndef JSON_USE_IMPLICIT_CONVERSIONS
2725 #define JSON_USE_IMPLICIT_CONVERSIONS 1
2726#endif
2727
2728#if JSON_USE_IMPLICIT_CONVERSIONS
2729 #define JSON_EXPLICIT
2730#else
2731 #define JSON_EXPLICIT explicit
2732#endif
2733
2734#ifndef JSON_DIAGNOSTICS
2735 #define JSON_DIAGNOSTICS 0
2736#endif
2737
2738
2739namespace nlohmann
2740{
2741namespace detail
2742{
2743
2757template<typename StringType>
2758inline void replace_substring(StringType& s, const StringType& f,
2759 const StringType& t)
2760{
2761 JSON_ASSERT(!f.empty());
2762 for (auto pos = s.find(f); // find first occurrence of f
2763 pos != StringType::npos; // make sure f was found
2764 s.replace(pos, f.size(), t), // replace with t, and
2765 pos = s.find(f, pos + t.size())) // find next occurrence of f
2766 {}
2767}
2768
2776template<typename StringType>
2777inline StringType escape(StringType s)
2778{
2779 replace_substring(s, StringType{"~"}, StringType{"~0"});
2780 replace_substring(s, StringType{"/"}, StringType{"~1"});
2781 return s;
2782}
2783
2791template<typename StringType>
2792static void unescape(StringType& s)
2793{
2794 replace_substring(s, StringType{"~1"}, StringType{"/"});
2795 replace_substring(s, StringType{"~0"}, StringType{"~"});
2796}
2797
2798} // namespace detail
2799} // namespace nlohmann
2800
2801// #include <nlohmann/detail/input/position_t.hpp>
2802
2803
2804#include <cstddef> // size_t
2805
2806namespace nlohmann
2807{
2808namespace detail
2809{
2812{
2814 std::size_t chars_read_total = 0;
2818 std::size_t lines_read = 0;
2819
2821 constexpr operator size_t() const
2822 {
2823 return chars_read_total;
2824 }
2825};
2826
2827} // namespace detail
2828} // namespace nlohmann
2829
2830// #include <nlohmann/detail/macro_scope.hpp>
2831
2832// #include <nlohmann/detail/meta/cpp_future.hpp>
2833
2834
2835#include <cstddef> // size_t
2836#include <type_traits> // conditional, enable_if, false_type, integral_constant, is_constructible, is_integral, is_same, remove_cv, remove_reference, true_type
2837#include <utility> // index_sequence, make_index_sequence, index_sequence_for
2838
2839// #include <nlohmann/detail/macro_scope.hpp>
2840
2841
2842namespace nlohmann
2843{
2844namespace detail
2845{
2846
2847template<typename T>
2848using uncvref_t = typename std::remove_cv<typename std::remove_reference<T>::type>::type;
2849
2850#ifdef JSON_HAS_CPP_14
2851
2852// the following utilities are natively available in C++14
2853using std::enable_if_t;
2854using std::index_sequence;
2855using std::make_index_sequence;
2856using std::index_sequence_for;
2857
2858#else
2859
2860// alias templates to reduce boilerplate
2861template<bool B, typename T = void>
2862using enable_if_t = typename std::enable_if<B, T>::type;
2863
2864// The following code is taken from https://github.com/abseil/abseil-cpp/blob/10cb35e459f5ecca5b2ff107635da0bfa41011b4/absl/utility/utility.h
2865// which is part of Google Abseil (https://github.com/abseil/abseil-cpp), licensed under the Apache License 2.0.
2866
2868
2869// integer_sequence
2870//
2871// Class template representing a compile-time integer sequence. An instantiation
2872// of `integer_sequence<T, Ints...>` has a sequence of integers encoded in its
2873// type through its template arguments (which is a common need when
2874// working with C++11 variadic templates). `absl::integer_sequence` is designed
2875// to be a drop-in replacement for C++14's `std::integer_sequence`.
2876//
2877// Example:
2878//
2879// template< class T, T... Ints >
2880// void user_function(integer_sequence<T, Ints...>);
2881//
2882// int main()
2883// {
2884// // user_function's `T` will be deduced to `int` and `Ints...`
2885// // will be deduced to `0, 1, 2, 3, 4`.
2886// user_function(make_integer_sequence<int, 5>());
2887// }
2888template <typename T, T... Ints>
2890{
2891 using value_type = T;
2892 static constexpr std::size_t size() noexcept
2893 {
2894 return sizeof...(Ints);
2895 }
2896};
2897
2898// index_sequence
2899//
2900// A helper template for an `integer_sequence` of `size_t`,
2901// `absl::index_sequence` is designed to be a drop-in replacement for C++14's
2902// `std::index_sequence`.
2903template <size_t... Ints>
2905
2906namespace utility_internal
2907{
2908
2909template <typename Seq, size_t SeqSize, size_t Rem>
2910struct Extend;
2911
2912// Note that SeqSize == sizeof...(Ints). It's passed explicitly for efficiency.
2913template <typename T, T... Ints, size_t SeqSize>
2914struct Extend<integer_sequence<T, Ints...>, SeqSize, 0>
2915{
2916 using type = integer_sequence < T, Ints..., (Ints + SeqSize)... >;
2917};
2918
2919template <typename T, T... Ints, size_t SeqSize>
2920struct Extend<integer_sequence<T, Ints...>, SeqSize, 1>
2921{
2922 using type = integer_sequence < T, Ints..., (Ints + SeqSize)..., 2 * SeqSize >;
2923};
2924
2925// Recursion helper for 'make_integer_sequence<T, N>'.
2926// 'Gen<T, N>::type' is an alias for 'integer_sequence<T, 0, 1, ... N-1>'.
2927template <typename T, size_t N>
2928struct Gen
2929{
2930 using type =
2931 typename Extend < typename Gen < T, N / 2 >::type, N / 2, N % 2 >::type;
2932};
2933
2934template <typename T>
2935struct Gen<T, 0>
2936{
2938};
2939
2940} // namespace utility_internal
2941
2942// Compile-time sequences of integers
2943
2944// make_integer_sequence
2945//
2946// This template alias is equivalent to
2947// `integer_sequence<int, 0, 1, ..., N-1>`, and is designed to be a drop-in
2948// replacement for C++14's `std::make_integer_sequence`.
2949template <typename T, T N>
2951
2952// make_index_sequence
2953//
2954// This template alias is equivalent to `index_sequence<0, 1, ..., N-1>`,
2955// and is designed to be a drop-in replacement for C++14's
2956// `std::make_index_sequence`.
2957template <size_t N>
2959
2960// index_sequence_for
2961//
2962// Converts a typename pack into an index sequence of the same length, and
2963// is designed to be a drop-in replacement for C++14's
2964// `std::index_sequence_for()`
2965template <typename... Ts>
2967
2969
2970#endif
2971
2972// dispatch utility (taken from ranges-v3)
2973template<unsigned N> struct priority_tag : priority_tag < N - 1 > {};
2974template<> struct priority_tag<0> {};
2975
2976// taken from ranges-v3
2977template<typename T>
2979{
2980 static constexpr T value{};
2981};
2982
2983#ifndef JSON_HAS_CPP_17
2984
2985 template<typename T>
2986 constexpr T static_const<T>::value; // NOLINT(readability-redundant-declaration)
2987
2988#endif
2989
2990} // namespace detail
2991} // namespace nlohmann
2992
2993// #include <nlohmann/detail/meta/type_traits.hpp>
2994
2995
2996#include <limits> // numeric_limits
2997#include <type_traits> // false_type, is_constructible, is_integral, is_same, true_type
2998#include <utility> // declval
2999#include <tuple> // tuple
3000
3001// #include <nlohmann/detail/macro_scope.hpp>
3002
3003
3004// #include <nlohmann/detail/iterators/iterator_traits.hpp>
3005
3006
3007#include <iterator> // random_access_iterator_tag
3008
3009// #include <nlohmann/detail/meta/void_t.hpp>
3010
3011// #include <nlohmann/detail/meta/cpp_future.hpp>
3012
3013
3014namespace nlohmann
3015{
3016namespace detail
3017{
3018template<typename It, typename = void>
3020
3021template<typename It>
3023 It,
3024 void_t<typename It::difference_type, typename It::value_type, typename It::pointer,
3025 typename It::reference, typename It::iterator_category >>
3026{
3027 using difference_type = typename It::difference_type;
3028 using value_type = typename It::value_type;
3029 using pointer = typename It::pointer;
3030 using reference = typename It::reference;
3031 using iterator_category = typename It::iterator_category;
3032};
3033
3034// This is required as some compilers implement std::iterator_traits in a way that
3035// doesn't work with SFINAE. See https://github.com/nlohmann/json/issues/1341.
3036template<typename T, typename = void>
3038{
3039};
3040
3041template<typename T>
3042struct iterator_traits < T, enable_if_t < !std::is_pointer<T>::value >>
3043 : iterator_types<T>
3044{
3045};
3046
3047template<typename T>
3049{
3050 using iterator_category = std::random_access_iterator_tag;
3051 using value_type = T;
3053 using pointer = T*;
3054 using reference = T&;
3055};
3056} // namespace detail
3057} // namespace nlohmann
3058
3059// #include <nlohmann/detail/meta/call_std/begin.hpp>
3060
3061
3062// #include <nlohmann/detail/macro_scope.hpp>
3063
3064
3065namespace nlohmann
3066{
3068} // namespace nlohmann
3069
3070// #include <nlohmann/detail/meta/call_std/end.hpp>
3071
3072
3073// #include <nlohmann/detail/macro_scope.hpp>
3074
3075
3076namespace nlohmann
3077{
3079} // namespace nlohmann
3080
3081// #include <nlohmann/detail/meta/cpp_future.hpp>
3082
3083// #include <nlohmann/detail/meta/detected.hpp>
3084
3085// #include <nlohmann/json_fwd.hpp>
3086#ifndef INCLUDE_NLOHMANN_JSON_FWD_HPP_
3087#define INCLUDE_NLOHMANN_JSON_FWD_HPP_
3088
3089#include <cstdint> // int64_t, uint64_t
3090#include <map> // map
3091#include <memory> // allocator
3092#include <string> // string
3093#include <vector> // vector
3094
3100namespace nlohmann
3101{
3109template<typename T = void, typename SFINAE = void>
3110struct adl_serializer;
3111
3114template<template<typename U, typename V, typename... Args> class ObjectType =
3115 std::map,
3116 template<typename U, typename... Args> class ArrayType = std::vector,
3117 class StringType = std::string, class BooleanType = bool,
3118 class NumberIntegerType = std::int64_t,
3119 class NumberUnsignedType = std::uint64_t,
3120 class NumberFloatType = double,
3121 template<typename U> class AllocatorType = std::allocator,
3122 template<typename T, typename SFINAE = void> class JSONSerializer =
3123 adl_serializer,
3124 class BinaryType = std::vector<std::uint8_t>>
3125class basic_json;
3126
3129template<typename BasicJsonType>
3130class json_pointer;
3131
3137
3140template<class Key, class T, class IgnoredLess, class Allocator>
3141struct ordered_map;
3142
3146
3147} // namespace nlohmann
3148
3149#endif // INCLUDE_NLOHMANN_JSON_FWD_HPP_
3150
3151
3152namespace nlohmann
3153{
3162namespace detail
3163{
3165// helpers //
3167
3168// Note to maintainers:
3169//
3170// Every trait in this file expects a non CV-qualified type.
3171// The only exceptions are in the 'aliases for detected' section
3172// (i.e. those of the form: decltype(T::member_function(std::declval<T>())))
3173//
3174// In this case, T has to be properly CV-qualified to constraint the function arguments
3175// (e.g. to_json(BasicJsonType&, const T&))
3176
3177template<typename> struct is_basic_json : std::false_type {};
3178
3180struct is_basic_json<NLOHMANN_BASIC_JSON_TPL> : std::true_type {};
3181
3182// used by exceptions create() member functions
3183// true_type for pointer to possibly cv-qualified basic_json or std::nullptr_t
3184// false_type otherwise
3185template<typename BasicJsonContext>
3187 std::integral_constant < bool,
3188 is_basic_json<typename std::remove_cv<typename std::remove_pointer<BasicJsonContext>::type>::type>::value
3189 || std::is_same<BasicJsonContext, std::nullptr_t>::value >
3190{};
3191
3193// json_ref helpers //
3195
3196template<typename>
3197class json_ref;
3198
3199template<typename>
3200struct is_json_ref : std::false_type {};
3201
3202template<typename T>
3203struct is_json_ref<json_ref<T>> : std::true_type {};
3204
3206// aliases for detected //
3208
3209template<typename T>
3210using mapped_type_t = typename T::mapped_type;
3211
3212template<typename T>
3213using key_type_t = typename T::key_type;
3214
3215template<typename T>
3216using value_type_t = typename T::value_type;
3217
3218template<typename T>
3219using difference_type_t = typename T::difference_type;
3220
3221template<typename T>
3222using pointer_t = typename T::pointer;
3223
3224template<typename T>
3225using reference_t = typename T::reference;
3226
3227template<typename T>
3228using iterator_category_t = typename T::iterator_category;
3229
3230template<typename T, typename... Args>
3231using to_json_function = decltype(T::to_json(std::declval<Args>()...));
3232
3233template<typename T, typename... Args>
3234using from_json_function = decltype(T::from_json(std::declval<Args>()...));
3235
3236template<typename T, typename U>
3237using get_template_function = decltype(std::declval<T>().template get<U>());
3238
3239// trait checking if JSONSerializer<T>::from_json(json const&, udt&) exists
3240template<typename BasicJsonType, typename T, typename = void>
3241struct has_from_json : std::false_type {};
3242
3243// trait checking if j.get<T> is valid
3244// use this trait instead of std::is_constructible or std::is_convertible,
3245// both rely on, or make use of implicit conversions, and thus fail when T
3246// has several constructors/operator= (see https://github.com/nlohmann/json/issues/958)
3247template <typename BasicJsonType, typename T>
3252
3253template<typename BasicJsonType, typename T>
3254struct has_from_json < BasicJsonType, T, enable_if_t < !is_basic_json<T>::value >>
3255{
3256 using serializer = typename BasicJsonType::template json_serializer<T, void>;
3257
3258 static constexpr bool value =
3260 const BasicJsonType&, T&>::value;
3261};
3262
3263// This trait checks if JSONSerializer<T>::from_json(json const&) exists
3264// this overload is used for non-default-constructible user-defined-types
3265template<typename BasicJsonType, typename T, typename = void>
3266struct has_non_default_from_json : std::false_type {};
3267
3268template<typename BasicJsonType, typename T>
3269struct has_non_default_from_json < BasicJsonType, T, enable_if_t < !is_basic_json<T>::value >>
3270{
3271 using serializer = typename BasicJsonType::template json_serializer<T, void>;
3272
3273 static constexpr bool value =
3275 const BasicJsonType&>::value;
3276};
3277
3278// This trait checks if BasicJsonType::json_serializer<T>::to_json exists
3279// Do not evaluate the trait when T is a basic_json type, to avoid template instantiation infinite recursion.
3280template<typename BasicJsonType, typename T, typename = void>
3281struct has_to_json : std::false_type {};
3282
3283template<typename BasicJsonType, typename T>
3284struct has_to_json < BasicJsonType, T, enable_if_t < !is_basic_json<T>::value >>
3285{
3286 using serializer = typename BasicJsonType::template json_serializer<T, void>;
3287
3288 static constexpr bool value =
3290 T>::value;
3291};
3292
3293template<typename T>
3294using detect_key_compare = typename T::key_compare;
3295
3296template<typename T>
3297struct has_key_compare : std::integral_constant<bool, is_detected<detect_key_compare, T>::value> {};
3298
3299// obtains the actual object key comparator
3300template<typename BasicJsonType>
3302{
3303 using object_t = typename BasicJsonType::object_t;
3304 using object_comparator_t = typename BasicJsonType::default_object_comparator_t;
3305 using type = typename std::conditional < has_key_compare<object_t>::value,
3306 typename object_t::key_compare, object_comparator_t>::type;
3307};
3308
3309template<typename BasicJsonType>
3311
3313// is_ functions //
3315
3316// https://en.cppreference.com/w/cpp/types/conjunction
3317template<class...> struct conjunction : std::true_type { };
3318template<class B> struct conjunction<B> : B { };
3319template<class B, class... Bn>
3320struct conjunction<B, Bn...>
3321: std::conditional<bool(B::value), conjunction<Bn...>, B>::type {};
3322
3323// https://en.cppreference.com/w/cpp/types/negation
3324template<class B> struct negation : std::integral_constant < bool, !B::value > { };
3325
3326// Reimplementation of is_constructible and is_default_constructible, due to them being broken for
3327// std::pair and std::tuple until LWG 2367 fix (see https://cplusplus.github.io/LWG/lwg-defects.html#2367).
3328// This causes compile errors in e.g. clang 3.5 or gcc 4.9.
3329template <typename T>
3330struct is_default_constructible : std::is_default_constructible<T> {};
3331
3332template <typename T1, typename T2>
3333struct is_default_constructible<std::pair<T1, T2>>
3334 : conjunction<is_default_constructible<T1>, is_default_constructible<T2>> {};
3335
3336template <typename T1, typename T2>
3337struct is_default_constructible<const std::pair<T1, T2>>
3338 : conjunction<is_default_constructible<T1>, is_default_constructible<T2>> {};
3339
3340template <typename... Ts>
3341struct is_default_constructible<std::tuple<Ts...>>
3342 : conjunction<is_default_constructible<Ts>...> {};
3343
3344template <typename... Ts>
3345struct is_default_constructible<const std::tuple<Ts...>>
3346 : conjunction<is_default_constructible<Ts>...> {};
3347
3348
3349template <typename T, typename... Args>
3350struct is_constructible : std::is_constructible<T, Args...> {};
3351
3352template <typename T1, typename T2>
3353struct is_constructible<std::pair<T1, T2>> : is_default_constructible<std::pair<T1, T2>> {};
3354
3355template <typename T1, typename T2>
3356struct is_constructible<const std::pair<T1, T2>> : is_default_constructible<const std::pair<T1, T2>> {};
3357
3358template <typename... Ts>
3359struct is_constructible<std::tuple<Ts...>> : is_default_constructible<std::tuple<Ts...>> {};
3360
3361template <typename... Ts>
3362struct is_constructible<const std::tuple<Ts...>> : is_default_constructible<const std::tuple<Ts...>> {};
3363
3364
3365template<typename T, typename = void>
3366struct is_iterator_traits : std::false_type {};
3367
3368template<typename T>
3382
3383template<typename T>
3385{
3386 private:
3387 using t_ref = typename std::add_lvalue_reference<T>::type;
3388
3389 using iterator = detected_t<result_of_begin, t_ref>;
3390 using sentinel = detected_t<result_of_end, t_ref>;
3391
3392 // to be 100% correct, it should use https://en.cppreference.com/w/cpp/iterator/input_or_output_iterator
3393 // and https://en.cppreference.com/w/cpp/iterator/sentinel_for
3394 // but reimplementing these would be too much work, as a lot of other concepts are used underneath
3395 static constexpr auto is_iterator_begin =
3397
3398 public:
3399 static constexpr bool value = !std::is_same<iterator, nonesuch>::value && !std::is_same<sentinel, nonesuch>::value && is_iterator_begin;
3400};
3401
3402template<typename R>
3403using iterator_t = enable_if_t<is_range<R>::value, result_of_begin<decltype(std::declval<R&>())>>;
3404
3405template<typename T>
3407
3408// The following implementation of is_complete_type is taken from
3409// https://blogs.msdn.microsoft.com/vcblog/2015/12/02/partial-support-for-expression-sfinae-in-vs-2015-update-1/
3410// and is written by Xiang Fan who agreed to using it in this library.
3411
3412template<typename T, typename = void>
3413struct is_complete_type : std::false_type {};
3414
3415template<typename T>
3416struct is_complete_type<T, decltype(void(sizeof(T)))> : std::true_type {};
3417
3418template<typename BasicJsonType, typename CompatibleObjectType,
3419 typename = void>
3420struct is_compatible_object_type_impl : std::false_type {};
3421
3422template<typename BasicJsonType, typename CompatibleObjectType>
3424 BasicJsonType, CompatibleObjectType,
3425 enable_if_t < is_detected<mapped_type_t, CompatibleObjectType>::value&&
3426 is_detected<key_type_t, CompatibleObjectType>::value >>
3427{
3428 using object_t = typename BasicJsonType::object_t;
3429
3430 // macOS's is_constructible does not play well with nonesuch...
3431 static constexpr bool value =
3432 is_constructible<typename object_t::key_type,
3433 typename CompatibleObjectType::key_type>::value &&
3434 is_constructible<typename object_t::mapped_type,
3435 typename CompatibleObjectType::mapped_type>::value;
3436};
3437
3438template<typename BasicJsonType, typename CompatibleObjectType>
3440 : is_compatible_object_type_impl<BasicJsonType, CompatibleObjectType> {};
3441
3442template<typename BasicJsonType, typename ConstructibleObjectType,
3443 typename = void>
3444struct is_constructible_object_type_impl : std::false_type {};
3445
3446template<typename BasicJsonType, typename ConstructibleObjectType>
3448 BasicJsonType, ConstructibleObjectType,
3449 enable_if_t < is_detected<mapped_type_t, ConstructibleObjectType>::value&&
3450 is_detected<key_type_t, ConstructibleObjectType>::value >>
3451{
3452 using object_t = typename BasicJsonType::object_t;
3453
3454 static constexpr bool value =
3456 (std::is_move_assignable<ConstructibleObjectType>::value ||
3457 std::is_copy_assignable<ConstructibleObjectType>::value) &&
3458 (is_constructible<typename ConstructibleObjectType::key_type,
3459 typename object_t::key_type>::value &&
3460 std::is_same <
3461 typename object_t::mapped_type,
3462 typename ConstructibleObjectType::mapped_type >::value)) ||
3463 (has_from_json<BasicJsonType,
3464 typename ConstructibleObjectType::mapped_type>::value ||
3466 BasicJsonType,
3467 typename ConstructibleObjectType::mapped_type >::value);
3468};
3469
3470template<typename BasicJsonType, typename ConstructibleObjectType>
3472 : is_constructible_object_type_impl<BasicJsonType,
3473 ConstructibleObjectType> {};
3474
3475template<typename BasicJsonType, typename CompatibleStringType>
3481
3482template<typename BasicJsonType, typename ConstructibleStringType>
3484{
3485 static constexpr auto value =
3486 is_constructible<ConstructibleStringType,
3487 typename BasicJsonType::string_t>::value;
3488};
3489
3490template<typename BasicJsonType, typename CompatibleArrayType, typename = void>
3491struct is_compatible_array_type_impl : std::false_type {};
3492
3493template<typename BasicJsonType, typename CompatibleArrayType>
3495 BasicJsonType, CompatibleArrayType,
3496 enable_if_t <
3497 is_detected<iterator_t, CompatibleArrayType>::value&&
3498 is_iterator_traits<iterator_traits<detected_t<iterator_t, CompatibleArrayType>>>::value&&
3499// special case for types like std::filesystem::path whose iterator's value_type are themselves
3500// c.f. https://github.com/nlohmann/json/pull/3073
3501 !std::is_same<CompatibleArrayType, detected_t<range_value_t, CompatibleArrayType>>::value >>
3502{
3503 static constexpr bool value =
3504 is_constructible<BasicJsonType,
3506};
3507
3508template<typename BasicJsonType, typename CompatibleArrayType>
3510 : is_compatible_array_type_impl<BasicJsonType, CompatibleArrayType> {};
3511
3512template<typename BasicJsonType, typename ConstructibleArrayType, typename = void>
3513struct is_constructible_array_type_impl : std::false_type {};
3514
3515template<typename BasicJsonType, typename ConstructibleArrayType>
3517 BasicJsonType, ConstructibleArrayType,
3518 enable_if_t<std::is_same<ConstructibleArrayType,
3519 typename BasicJsonType::value_type>::value >>
3520 : std::true_type {};
3521
3522template<typename BasicJsonType, typename ConstructibleArrayType>
3524 BasicJsonType, ConstructibleArrayType,
3525 enable_if_t < !std::is_same<ConstructibleArrayType,
3526 typename BasicJsonType::value_type>::value&&
3527 !is_compatible_string_type<BasicJsonType, ConstructibleArrayType>::value&&
3528 is_default_constructible<ConstructibleArrayType>::value&&
3529(std::is_move_assignable<ConstructibleArrayType>::value ||
3530 std::is_copy_assignable<ConstructibleArrayType>::value)&&
3531is_detected<iterator_t, ConstructibleArrayType>::value&&
3532is_iterator_traits<iterator_traits<detected_t<iterator_t, ConstructibleArrayType>>>::value&&
3533is_detected<range_value_t, ConstructibleArrayType>::value&&
3534// special case for types like std::filesystem::path whose iterator's value_type are themselves
3535// c.f. https://github.com/nlohmann/json/pull/3073
3536!std::is_same<ConstructibleArrayType, detected_t<range_value_t, ConstructibleArrayType>>::value&&
3538 detected_t<range_value_t, ConstructibleArrayType >>::value >>
3539{
3541
3542 static constexpr bool value =
3543 std::is_same<value_type,
3544 typename BasicJsonType::array_t::value_type>::value ||
3545 has_from_json<BasicJsonType,
3548 BasicJsonType,
3550};
3551
3552template<typename BasicJsonType, typename ConstructibleArrayType>
3554 : is_constructible_array_type_impl<BasicJsonType, ConstructibleArrayType> {};
3555
3556template<typename RealIntegerType, typename CompatibleNumberIntegerType,
3557 typename = void>
3558struct is_compatible_integer_type_impl : std::false_type {};
3559
3560template<typename RealIntegerType, typename CompatibleNumberIntegerType>
3562 RealIntegerType, CompatibleNumberIntegerType,
3563 enable_if_t < std::is_integral<RealIntegerType>::value&&
3564 std::is_integral<CompatibleNumberIntegerType>::value&&
3565 !std::is_same<bool, CompatibleNumberIntegerType>::value >>
3566{
3567 // is there an assert somewhere on overflows?
3568 using RealLimits = std::numeric_limits<RealIntegerType>;
3569 using CompatibleLimits = std::numeric_limits<CompatibleNumberIntegerType>;
3570
3571 static constexpr auto value =
3572 is_constructible<RealIntegerType,
3573 CompatibleNumberIntegerType>::value &&
3574 CompatibleLimits::is_integer &&
3575 RealLimits::is_signed == CompatibleLimits::is_signed;
3576};
3577
3578template<typename RealIntegerType, typename CompatibleNumberIntegerType>
3580 : is_compatible_integer_type_impl<RealIntegerType,
3581 CompatibleNumberIntegerType> {};
3582
3583template<typename BasicJsonType, typename CompatibleType, typename = void>
3584struct is_compatible_type_impl: std::false_type {};
3585
3586template<typename BasicJsonType, typename CompatibleType>
3588 BasicJsonType, CompatibleType,
3589 enable_if_t<is_complete_type<CompatibleType>::value >>
3590{
3591 static constexpr bool value =
3593};
3594
3595template<typename BasicJsonType, typename CompatibleType>
3597 : is_compatible_type_impl<BasicJsonType, CompatibleType> {};
3598
3599template<typename T1, typename T2>
3600struct is_constructible_tuple : std::false_type {};
3601
3602template<typename T1, typename... Args>
3603struct is_constructible_tuple<T1, std::tuple<Args...>> : conjunction<is_constructible<T1, Args>...> {};
3604
3605template<typename BasicJsonType, typename T>
3606struct is_json_iterator_of : std::false_type {};
3607
3608template<typename BasicJsonType>
3609struct is_json_iterator_of<BasicJsonType, typename BasicJsonType::iterator> : std::true_type {};
3610
3611template<typename BasicJsonType>
3612struct is_json_iterator_of<BasicJsonType, typename BasicJsonType::const_iterator> : std::true_type
3613{};
3614
3615// checks if a given type T is a template specialization of Primary
3616template<template <typename...> class Primary, typename T>
3617struct is_specialization_of : std::false_type {};
3618
3619template<template <typename...> class Primary, typename... Args>
3620struct is_specialization_of<Primary, Primary<Args...>> : std::true_type {};
3621
3622template<typename T>
3624
3625// checks if A and B are comparable using Compare functor
3626template<typename Compare, typename A, typename B, typename = void>
3627struct is_comparable : std::false_type {};
3628
3629template<typename Compare, typename A, typename B>
3630struct is_comparable<Compare, A, B, void_t<
3631decltype(std::declval<Compare>()(std::declval<A>(), std::declval<B>())),
3632decltype(std::declval<Compare>()(std::declval<B>(), std::declval<A>()))
3633>> : std::true_type {};
3634
3635// checks if BasicJsonType::object_t::key_type and KeyType are comparable using Compare functor
3636template<typename BasicJsonType, typename KeyType>
3638 typename BasicJsonType::object_comparator_t,
3640 KeyType >::type;
3641
3642template<typename T>
3643using detect_is_transparent = typename T::is_transparent;
3644
3645// type trait to check if KeyType can be used as object key
3646// true if:
3647// - KeyType is comparable with BasicJsonType::object_t::key_type
3648// - if ExcludeObjectKeyType is true, KeyType is not BasicJsonType::object_t::key_type
3649// - the comparator is transparent or RequireTransparentComparator is false
3650// - KeyType is not a JSON iterator or json_pointer
3651template<typename BasicJsonType, typename KeyTypeCVRef, bool RequireTransparentComparator = true,
3652 bool ExcludeObjectKeyType = RequireTransparentComparator, typename KeyType = uncvref_t<KeyTypeCVRef>>
3653using is_usable_as_key_type = typename std::conditional <
3655 && !(ExcludeObjectKeyType && std::is_same<KeyType,
3656 typename BasicJsonType::object_t::key_type>::value)
3657 && (!RequireTransparentComparator || is_detected <
3659 typename BasicJsonType::object_comparator_t >::value)
3662 std::true_type,
3663 std::false_type >::type;
3664
3665template<typename ObjectType, typename KeyType>
3666using detect_erase_with_key_type = decltype(std::declval<ObjectType&>().erase(std::declval<KeyType>()));
3667
3668// type trait to check if object_t has an erase() member functions accepting KeyType
3669template<typename BasicJsonType, typename KeyType>
3670using has_erase_with_key_type = typename std::conditional <
3671 is_detected <
3673 typename BasicJsonType::object_t, KeyType >::value,
3674 std::true_type,
3675 std::false_type >::type;
3676
3677// a naive helper to check if a type is an ordered_map (exploits the fact that
3678// ordered_map inherits capacity() from std::vector)
3679template <typename T>
3681{
3682 using one = char;
3683
3684 struct two
3685 {
3686 char x[2]; // NOLINT(cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays)
3687 };
3688
3689 template <typename C> static one test( decltype(&C::capacity) ) ;
3690 template <typename C> static two test(...);
3691
3692 enum { value = sizeof(test<T>(nullptr)) == sizeof(char) }; // NOLINT(cppcoreguidelines-pro-type-vararg,hicpp-vararg)
3693};
3694
3695// to avoid useless casts (see https://github.com/nlohmann/json/issues/2893#issuecomment-889152324)
3696template < typename T, typename U, enable_if_t < !std::is_same<T, U>::value, int > = 0 >
3698{
3699 return static_cast<T>(value);
3700}
3701
3702template<typename T, typename U, enable_if_t<std::is_same<T, U>::value, int> = 0>
3704{
3705 return value;
3706}
3707
3708} // namespace detail
3709} // namespace nlohmann
3710
3711// #include <nlohmann/detail/string_concat.hpp>
3712
3713
3714#include <cstring> // strlen
3715#include <string> // string
3716#include <utility> // forward
3717
3718// #include <nlohmann/detail/meta/cpp_future.hpp>
3719
3720// #include <nlohmann/detail/meta/detected.hpp>
3721
3722
3723namespace nlohmann
3724{
3725namespace detail
3726{
3727
3728inline std::size_t concat_length()
3729{
3730 return 0;
3731}
3732
3733template<typename... Args>
3734inline std::size_t concat_length(const char* cstr, Args&& ... rest);
3735
3736template<typename StringType, typename... Args>
3737inline std::size_t concat_length(const StringType& str, Args&& ... rest);
3738
3739template<typename... Args>
3740inline std::size_t concat_length(const char /*c*/, Args&& ... rest)
3741{
3742 return 1 + concat_length(std::forward<Args>(rest)...);
3743}
3744
3745template<typename... Args>
3746inline std::size_t concat_length(const char* cstr, Args&& ... rest)
3747{
3748 // cppcheck-suppress ignoredReturnValue
3749 return ::strlen(cstr) + concat_length(std::forward<Args>(rest)...);
3750}
3751
3752template<typename StringType, typename... Args>
3753inline std::size_t concat_length(const StringType& str, Args&& ... rest)
3754{
3755 return str.size() + concat_length(std::forward<Args>(rest)...);
3756}
3757
3758template<typename OutStringType>
3759inline void concat_into(OutStringType& /*out*/)
3760{}
3761
3762template<typename StringType, typename Arg>
3763using string_can_append = decltype(std::declval<StringType&>().append(std::declval < Arg && > ()));
3764
3765template<typename StringType, typename Arg>
3767
3768template<typename StringType, typename Arg>
3769using string_can_append_op = decltype(std::declval<StringType&>() += std::declval < Arg && > ());
3770
3771template<typename StringType, typename Arg>
3773
3774template<typename StringType, typename Arg>
3775using string_can_append_iter = decltype(std::declval<StringType&>().append(std::declval<const Arg&>().begin(), std::declval<const Arg&>().end()));
3776
3777template<typename StringType, typename Arg>
3779
3780template<typename StringType, typename Arg>
3781using string_can_append_data = decltype(std::declval<StringType&>().append(std::declval<const Arg&>().data(), std::declval<const Arg&>().size()));
3782
3783template<typename StringType, typename Arg>
3785
3786template < typename OutStringType, typename Arg, typename... Args,
3787 enable_if_t < !detect_string_can_append<OutStringType, Arg>::value
3789inline void concat_into(OutStringType& out, Arg && arg, Args && ... rest);
3790
3791template < typename OutStringType, typename Arg, typename... Args,
3792 enable_if_t < !detect_string_can_append<OutStringType, Arg>::value
3795inline void concat_into(OutStringType& out, const Arg& arg, Args && ... rest);
3796
3797template < typename OutStringType, typename Arg, typename... Args,
3798 enable_if_t < !detect_string_can_append<OutStringType, Arg>::value
3802inline void concat_into(OutStringType& out, const Arg& arg, Args && ... rest);
3803
3804template<typename OutStringType, typename Arg, typename... Args,
3806inline void concat_into(OutStringType& out, Arg && arg, Args && ... rest)
3807{
3808 out.append(std::forward<Arg>(arg));
3809 concat_into(out, std::forward<Args>(rest)...);
3810}
3811
3812template < typename OutStringType, typename Arg, typename... Args,
3813 enable_if_t < !detect_string_can_append<OutStringType, Arg>::value
3814 && detect_string_can_append_op<OutStringType, Arg>::value, int > >
3815inline void concat_into(OutStringType& out, Arg&& arg, Args&& ... rest)
3816{
3817 out += std::forward<Arg>(arg);
3818 concat_into(out, std::forward<Args>(rest)...);
3819}
3820
3821template < typename OutStringType, typename Arg, typename... Args,
3822 enable_if_t < !detect_string_can_append<OutStringType, Arg>::value
3823 && !detect_string_can_append_op<OutStringType, Arg>::value
3824 && detect_string_can_append_iter<OutStringType, Arg>::value, int > >
3825inline void concat_into(OutStringType& out, const Arg& arg, Args&& ... rest)
3826{
3827 out.append(arg.begin(), arg.end());
3828 concat_into(out, std::forward<Args>(rest)...);
3829}
3830
3831template < typename OutStringType, typename Arg, typename... Args,
3832 enable_if_t < !detect_string_can_append<OutStringType, Arg>::value
3833 && !detect_string_can_append_op<OutStringType, Arg>::value
3834 && !detect_string_can_append_iter<OutStringType, Arg>::value
3835 && detect_string_can_append_data<OutStringType, Arg>::value, int > >
3836inline void concat_into(OutStringType& out, const Arg& arg, Args&& ... rest)
3837{
3838 out.append(arg.data(), arg.size());
3839 concat_into(out, std::forward<Args>(rest)...);
3840}
3841
3842template<typename OutStringType = std::string, typename... Args>
3843inline OutStringType concat(Args && ... args)
3844{
3845 OutStringType str;
3846 str.reserve(concat_length(std::forward<Args>(args)...));
3847 concat_into(str, std::forward<Args>(args)...);
3848 return str;
3849}
3850
3851} // namespace detail
3852} // namespace nlohmann
3853
3854
3855
3856namespace nlohmann
3857{
3858namespace detail
3859{
3861// exceptions //
3863
3867{
3868 public:
3870 const char* what() const noexcept override
3871 {
3872 return m.what();
3873 }
3874
3876 const int id; // NOLINT(cppcoreguidelines-non-private-member-variables-in-classes)
3877
3878 protected:
3880 exception(int id_, const char* what_arg) : id(id_), m(what_arg) {} // NOLINT(bugprone-throw-keyword-missing)
3881
3882 static std::string name(const std::string& ename, int id_)
3883 {
3884 return concat("[json.exception.", ename, '.', std::to_string(id_), "] ");
3885 }
3886
3887 static std::string diagnostics(std::nullptr_t /*leaf_element*/)
3888 {
3889 return "";
3890 }
3891
3892 template<typename BasicJsonType>
3893 static std::string diagnostics(const BasicJsonType* leaf_element)
3894 {
3895#if JSON_DIAGNOSTICS
3896 std::vector<std::string> tokens;
3897 for (const auto* current = leaf_element; current != nullptr && current->m_parent != nullptr; current = current->m_parent)
3898 {
3899 switch (current->m_parent->type())
3900 {
3901 case value_t::array:
3902 {
3903 for (std::size_t i = 0; i < current->m_parent->m_value.array->size(); ++i)
3904 {
3905 if (&current->m_parent->m_value.array->operator[](i) == current)
3906 {
3907 tokens.emplace_back(std::to_string(i));
3908 break;
3909 }
3910 }
3911 break;
3912 }
3913
3914 case value_t::object:
3915 {
3916 for (const auto& element : *current->m_parent->m_value.object)
3917 {
3918 if (&element.second == current)
3919 {
3920 tokens.emplace_back(element.first.c_str());
3921 break;
3922 }
3923 }
3924 break;
3925 }
3926
3927 case value_t::null: // LCOV_EXCL_LINE
3928 case value_t::string: // LCOV_EXCL_LINE
3929 case value_t::boolean: // LCOV_EXCL_LINE
3930 case value_t::number_integer: // LCOV_EXCL_LINE
3931 case value_t::number_unsigned: // LCOV_EXCL_LINE
3932 case value_t::number_float: // LCOV_EXCL_LINE
3933 case value_t::binary: // LCOV_EXCL_LINE
3934 case value_t::discarded: // LCOV_EXCL_LINE
3935 default: // LCOV_EXCL_LINE
3936 break; // LCOV_EXCL_LINE
3937 }
3938 }
3939
3940 if (tokens.empty())
3941 {
3942 return "";
3943 }
3944
3945 auto str = std::accumulate(tokens.rbegin(), tokens.rend(), std::string{},
3946 [](const std::string & a, const std::string & b)
3947 {
3948 return concat(a, '/', detail::escape(b));
3949 });
3950 return concat('(', str, ") ");
3951#else
3952 static_cast<void>(leaf_element);
3953 return "";
3954#endif
3955 }
3956
3957 private:
3959 std::runtime_error m;
3960};
3961
3965{
3966 public:
3976 template<typename BasicJsonContext, enable_if_t<is_basic_json_context<BasicJsonContext>::value, int> = 0>
3977 static parse_error create(int id_, const position_t& pos, const std::string& what_arg, BasicJsonContext context)
3978 {
3979 std::string w = concat(exception::name("parse_error", id_), "parse error",
3980 position_string(pos), ": ", exception::diagnostics(context), what_arg);
3981 return {id_, pos.chars_read_total, w.c_str()};
3982 }
3983
3984 template<typename BasicJsonContext, enable_if_t<is_basic_json_context<BasicJsonContext>::value, int> = 0>
3985 static parse_error create(int id_, std::size_t byte_, const std::string& what_arg, BasicJsonContext context)
3986 {
3987 std::string w = concat(exception::name("parse_error", id_), "parse error",
3988 (byte_ != 0 ? (concat(" at byte ", std::to_string(byte_))) : ""),
3989 ": ", exception::diagnostics(context), what_arg);
3990 return {id_, byte_, w.c_str()};
3991 }
3992
4002 const std::size_t byte;
4003
4004 private:
4005 parse_error(int id_, std::size_t byte_, const char* what_arg)
4006 : exception(id_, what_arg), byte(byte_) {}
4007
4008 static std::string position_string(const position_t& pos)
4009 {
4010 return concat(" at line ", std::to_string(pos.lines_read + 1),
4011 ", column ", std::to_string(pos.chars_read_current_line));
4012 }
4013};
4014
4018{
4019 public:
4020 template<typename BasicJsonContext, enable_if_t<is_basic_json_context<BasicJsonContext>::value, int> = 0>
4021 static invalid_iterator create(int id_, const std::string& what_arg, BasicJsonContext context)
4022 {
4023 std::string w = concat(exception::name("invalid_iterator", id_), exception::diagnostics(context), what_arg);
4024 return {id_, w.c_str()};
4025 }
4026
4027 private:
4029 invalid_iterator(int id_, const char* what_arg)
4030 : exception(id_, what_arg) {}
4031};
4032
4035class type_error : public exception
4036{
4037 public:
4038 template<typename BasicJsonContext, enable_if_t<is_basic_json_context<BasicJsonContext>::value, int> = 0>
4039 static type_error create(int id_, const std::string& what_arg, BasicJsonContext context)
4040 {
4041 std::string w = concat(exception::name("type_error", id_), exception::diagnostics(context), what_arg);
4042 return {id_, w.c_str()};
4043 }
4044
4045 private:
4047 type_error(int id_, const char* what_arg) : exception(id_, what_arg) {}
4048};
4049
4053{
4054 public:
4055 template<typename BasicJsonContext, enable_if_t<is_basic_json_context<BasicJsonContext>::value, int> = 0>
4056 static out_of_range create(int id_, const std::string& what_arg, BasicJsonContext context)
4057 {
4058 std::string w = concat(exception::name("out_of_range", id_), exception::diagnostics(context), what_arg);
4059 return {id_, w.c_str()};
4060 }
4061
4062 private:
4064 out_of_range(int id_, const char* what_arg) : exception(id_, what_arg) {}
4065};
4066
4070{
4071 public:
4072 template<typename BasicJsonContext, enable_if_t<is_basic_json_context<BasicJsonContext>::value, int> = 0>
4073 static other_error create(int id_, const std::string& what_arg, BasicJsonContext context)
4074 {
4075 std::string w = concat(exception::name("other_error", id_), exception::diagnostics(context), what_arg);
4076 return {id_, w.c_str()};
4077 }
4078
4079 private:
4081 other_error(int id_, const char* what_arg) : exception(id_, what_arg) {}
4082};
4083
4084} // namespace detail
4085} // namespace nlohmann
4086
4087// #include <nlohmann/detail/macro_scope.hpp>
4088
4089// #include <nlohmann/detail/meta/cpp_future.hpp>
4090
4091// #include <nlohmann/detail/meta/identity_tag.hpp>
4092
4093
4094namespace nlohmann
4095{
4096namespace detail
4097{
4098// dispatching helper struct
4099template <class T> struct identity_tag {};
4100} // namespace detail
4101} // namespace nlohmann
4102
4103// #include <nlohmann/detail/meta/type_traits.hpp>
4104
4105// #include <nlohmann/detail/string_concat.hpp>
4106
4107// #include <nlohmann/detail/value_t.hpp>
4108
4109
4110#if JSON_HAS_EXPERIMENTAL_FILESYSTEM
4111#include <experimental/filesystem>
4112namespace nlohmann::detail
4113{
4114namespace std_fs = std::experimental::filesystem;
4115} // namespace nlohmann::detail
4116#elif JSON_HAS_FILESYSTEM
4117#include <filesystem>
4118namespace nlohmann::detail
4119{
4120namespace std_fs = std::filesystem;
4121} // namespace nlohmann::detail
4122#endif
4123
4124namespace nlohmann
4125{
4126namespace detail
4127{
4128template<typename BasicJsonType>
4129void from_json(const BasicJsonType& j, typename std::nullptr_t& n)
4130{
4131 if (JSON_HEDLEY_UNLIKELY(!j.is_null()))
4132 {
4133 JSON_THROW(type_error::create(302, concat("type must be null, but is ", j.type_name()), &j));
4134 }
4135 n = nullptr;
4136}
4137
4138// overloads for basic_json template parameters
4139template < typename BasicJsonType, typename ArithmeticType,
4140 enable_if_t < std::is_arithmetic<ArithmeticType>::value&&
4141 !std::is_same<ArithmeticType, typename BasicJsonType::boolean_t>::value,
4142 int > = 0 >
4143void get_arithmetic_value(const BasicJsonType& j, ArithmeticType& val)
4144{
4145 switch (static_cast<value_t>(j))
4146 {
4148 {
4149 val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::number_unsigned_t*>());
4150 break;
4151 }
4153 {
4154 val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::number_integer_t*>());
4155 break;
4156 }
4158 {
4159 val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::number_float_t*>());
4160 break;
4161 }
4162
4163 case value_t::null:
4164 case value_t::object:
4165 case value_t::array:
4166 case value_t::string:
4167 case value_t::boolean:
4168 case value_t::binary:
4169 case value_t::discarded:
4170 default:
4171 JSON_THROW(type_error::create(302, concat("type must be number, but is ", j.type_name()), &j));
4172 }
4173}
4174
4175template<typename BasicJsonType>
4176void from_json(const BasicJsonType& j, typename BasicJsonType::boolean_t& b)
4177{
4178 if (JSON_HEDLEY_UNLIKELY(!j.is_boolean()))
4179 {
4180 JSON_THROW(type_error::create(302, concat("type must be boolean, but is ", j.type_name()), &j));
4181 }
4182 b = *j.template get_ptr<const typename BasicJsonType::boolean_t*>();
4183}
4184
4185template<typename BasicJsonType>
4186void from_json(const BasicJsonType& j, typename BasicJsonType::string_t& s)
4187{
4188 if (JSON_HEDLEY_UNLIKELY(!j.is_string()))
4189 {
4190 JSON_THROW(type_error::create(302, concat("type must be string, but is ", j.type_name()), &j));
4191 }
4192 s = *j.template get_ptr<const typename BasicJsonType::string_t*>();
4193}
4194
4195template <
4196 typename BasicJsonType, typename StringType,
4197 enable_if_t <
4198 std::is_assignable<StringType&, const typename BasicJsonType::string_t>::value
4199 && !std::is_same<typename BasicJsonType::string_t, StringType>::value
4200 && !is_json_ref<StringType>::value, int > = 0 >
4201void from_json(const BasicJsonType& j, StringType& s)
4202{
4203 if (JSON_HEDLEY_UNLIKELY(!j.is_string()))
4204 {
4205 JSON_THROW(type_error::create(302, concat("type must be string, but is ", j.type_name()), &j));
4206 }
4207
4208 s = *j.template get_ptr<const typename BasicJsonType::string_t*>();
4209}
4210
4211template<typename BasicJsonType>
4212void from_json(const BasicJsonType& j, typename BasicJsonType::number_float_t& val)
4213{
4214 get_arithmetic_value(j, val);
4215}
4216
4217template<typename BasicJsonType>
4218void from_json(const BasicJsonType& j, typename BasicJsonType::number_unsigned_t& val)
4219{
4220 get_arithmetic_value(j, val);
4221}
4222
4223template<typename BasicJsonType>
4224void from_json(const BasicJsonType& j, typename BasicJsonType::number_integer_t& val)
4225{
4226 get_arithmetic_value(j, val);
4227}
4228
4229template<typename BasicJsonType, typename EnumType,
4230 enable_if_t<std::is_enum<EnumType>::value, int> = 0>
4231void from_json(const BasicJsonType& j, EnumType& e)
4232{
4233 typename std::underlying_type<EnumType>::type val;
4234 get_arithmetic_value(j, val);
4235 e = static_cast<EnumType>(val);
4236}
4237
4238// forward_list doesn't have an insert method
4239template<typename BasicJsonType, typename T, typename Allocator,
4240 enable_if_t<is_getable<BasicJsonType, T>::value, int> = 0>
4241void from_json(const BasicJsonType& j, std::forward_list<T, Allocator>& l)
4242{
4243 if (JSON_HEDLEY_UNLIKELY(!j.is_array()))
4244 {
4245 JSON_THROW(type_error::create(302, concat("type must be array, but is ", j.type_name()), &j));
4246 }
4247 l.clear();
4248 std::transform(j.rbegin(), j.rend(),
4249 std::front_inserter(l), [](const BasicJsonType & i)
4250 {
4251 return i.template get<T>();
4252 });
4253}
4254
4255// valarray doesn't have an insert method
4256template<typename BasicJsonType, typename T,
4257 enable_if_t<is_getable<BasicJsonType, T>::value, int> = 0>
4258void from_json(const BasicJsonType& j, std::valarray<T>& l)
4259{
4260 if (JSON_HEDLEY_UNLIKELY(!j.is_array()))
4261 {
4262 JSON_THROW(type_error::create(302, concat("type must be array, but is ", j.type_name()), &j));
4263 }
4264 l.resize(j.size());
4265 std::transform(j.begin(), j.end(), std::begin(l),
4266 [](const BasicJsonType & elem)
4267 {
4268 return elem.template get<T>();
4269 });
4270}
4271
4272template<typename BasicJsonType, typename T, std::size_t N>
4273auto from_json(const BasicJsonType& j, T (&arr)[N]) // NOLINT(cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays)
4274-> decltype(j.template get<T>(), void())
4275{
4276 for (std::size_t i = 0; i < N; ++i)
4277 {
4278 arr[i] = j.at(i).template get<T>();
4279 }
4280}
4281
4282template<typename BasicJsonType>
4283void from_json_array_impl(const BasicJsonType& j, typename BasicJsonType::array_t& arr, priority_tag<3> /*unused*/)
4284{
4285 arr = *j.template get_ptr<const typename BasicJsonType::array_t*>();
4286}
4287
4288template<typename BasicJsonType, typename T, std::size_t N>
4289auto from_json_array_impl(const BasicJsonType& j, std::array<T, N>& arr,
4290 priority_tag<2> /*unused*/)
4291-> decltype(j.template get<T>(), void())
4292{
4293 for (std::size_t i = 0; i < N; ++i)
4294 {
4295 arr[i] = j.at(i).template get<T>();
4296 }
4297}
4298
4299template<typename BasicJsonType, typename ConstructibleArrayType,
4301 std::is_assignable<ConstructibleArrayType&, ConstructibleArrayType>::value,
4302 int> = 0>
4303auto from_json_array_impl(const BasicJsonType& j, ConstructibleArrayType& arr, priority_tag<1> /*unused*/)
4304-> decltype(
4305 arr.reserve(std::declval<typename ConstructibleArrayType::size_type>()),
4307 void())
4308{
4309 using std::end;
4310
4311 ConstructibleArrayType ret;
4312 ret.reserve(j.size());
4313 std::transform(j.begin(), j.end(),
4314 std::inserter(ret, end(ret)), [](const BasicJsonType & i)
4315 {
4316 // get<BasicJsonType>() returns *this, this won't call a from_json
4317 // method when value_type is BasicJsonType
4319 });
4320 arr = std::move(ret);
4321}
4322
4323template<typename BasicJsonType, typename ConstructibleArrayType,
4325 std::is_assignable<ConstructibleArrayType&, ConstructibleArrayType>::value,
4326 int> = 0>
4327void from_json_array_impl(const BasicJsonType& j, ConstructibleArrayType& arr,
4328 priority_tag<0> /*unused*/)
4329{
4330 using std::end;
4331
4332 ConstructibleArrayType ret;
4334 j.begin(), j.end(), std::inserter(ret, end(ret)),
4335 [](const BasicJsonType & i)
4336 {
4337 // get<BasicJsonType>() returns *this, this won't call a from_json
4338 // method when value_type is BasicJsonType
4340 });
4341 arr = std::move(ret);
4342}
4343
4344template < typename BasicJsonType, typename ConstructibleArrayType,
4345 enable_if_t <
4346 is_constructible_array_type<BasicJsonType, ConstructibleArrayType>::value&&
4347 !is_constructible_object_type<BasicJsonType, ConstructibleArrayType>::value&&
4349 !std::is_same<ConstructibleArrayType, typename BasicJsonType::binary_t>::value&&
4350 !is_basic_json<ConstructibleArrayType>::value,
4351 int > = 0 >
4352auto from_json(const BasicJsonType& j, ConstructibleArrayType& arr)
4353-> decltype(from_json_array_impl(j, arr, priority_tag<3> {}),
4355void())
4356{
4357 if (JSON_HEDLEY_UNLIKELY(!j.is_array()))
4358 {
4359 JSON_THROW(type_error::create(302, concat("type must be array, but is ", j.type_name()), &j));
4360 }
4361
4362 from_json_array_impl(j, arr, priority_tag<3> {});
4363}
4364
4365template < typename BasicJsonType, typename T, std::size_t... Idx >
4366std::array<T, sizeof...(Idx)> from_json_inplace_array_impl(BasicJsonType&& j,
4367 identity_tag<std::array<T, sizeof...(Idx)>> /*unused*/, index_sequence<Idx...> /*unused*/)
4368{
4369 return { { std::forward<BasicJsonType>(j).at(Idx).template get<T>()... } };
4370}
4371
4372template < typename BasicJsonType, typename T, std::size_t N >
4373auto from_json(BasicJsonType&& j, identity_tag<std::array<T, N>> tag)
4374-> decltype(from_json_inplace_array_impl(std::forward<BasicJsonType>(j), tag, make_index_sequence<N> {}))
4375{
4376 if (JSON_HEDLEY_UNLIKELY(!j.is_array()))
4377 {
4378 JSON_THROW(type_error::create(302, concat("type must be array, but is ", j.type_name()), &j));
4379 }
4380
4381 return from_json_inplace_array_impl(std::forward<BasicJsonType>(j), tag, make_index_sequence<N> {});
4382}
4383
4384template<typename BasicJsonType>
4385void from_json(const BasicJsonType& j, typename BasicJsonType::binary_t& bin)
4386{
4387 if (JSON_HEDLEY_UNLIKELY(!j.is_binary()))
4388 {
4389 JSON_THROW(type_error::create(302, concat("type must be binary, but is ", j.type_name()), &j));
4390 }
4391
4392 bin = *j.template get_ptr<const typename BasicJsonType::binary_t*>();
4393}
4394
4395template<typename BasicJsonType, typename ConstructibleObjectType,
4396 enable_if_t<is_constructible_object_type<BasicJsonType, ConstructibleObjectType>::value, int> = 0>
4397void from_json(const BasicJsonType& j, ConstructibleObjectType& obj)
4398{
4399 if (JSON_HEDLEY_UNLIKELY(!j.is_object()))
4400 {
4401 JSON_THROW(type_error::create(302, concat("type must be object, but is ", j.type_name()), &j));
4402 }
4403
4404 ConstructibleObjectType ret;
4405 const auto* inner_object = j.template get_ptr<const typename BasicJsonType::object_t*>();
4406 using value_type = typename ConstructibleObjectType::value_type;
4408 inner_object->begin(), inner_object->end(),
4409 std::inserter(ret, ret.begin()),
4410 [](typename BasicJsonType::object_t::value_type const & p)
4411 {
4412 return value_type(p.first, p.second.template get<typename ConstructibleObjectType::mapped_type>());
4413 });
4414 obj = std::move(ret);
4415}
4416
4417// overload for arithmetic types, not chosen for basic_json template arguments
4418// (BooleanType, etc..); note: Is it really necessary to provide explicit
4419// overloads for boolean_t etc. in case of a custom BooleanType which is not
4420// an arithmetic type?
4421template < typename BasicJsonType, typename ArithmeticType,
4422 enable_if_t <
4423 std::is_arithmetic<ArithmeticType>::value&&
4424 !std::is_same<ArithmeticType, typename BasicJsonType::number_unsigned_t>::value&&
4425 !std::is_same<ArithmeticType, typename BasicJsonType::number_integer_t>::value&&
4426 !std::is_same<ArithmeticType, typename BasicJsonType::number_float_t>::value&&
4427 !std::is_same<ArithmeticType, typename BasicJsonType::boolean_t>::value,
4428 int > = 0 >
4429void from_json(const BasicJsonType& j, ArithmeticType& val)
4430{
4431 switch (static_cast<value_t>(j))
4432 {
4434 {
4435 val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::number_unsigned_t*>());
4436 break;
4437 }
4439 {
4440 val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::number_integer_t*>());
4441 break;
4442 }
4444 {
4445 val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::number_float_t*>());
4446 break;
4447 }
4448 case value_t::boolean:
4449 {
4450 val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::boolean_t*>());
4451 break;
4452 }
4453
4454 case value_t::null:
4455 case value_t::object:
4456 case value_t::array:
4457 case value_t::string:
4458 case value_t::binary:
4459 case value_t::discarded:
4460 default:
4461 JSON_THROW(type_error::create(302, concat("type must be number, but is ", j.type_name()), &j));
4462 }
4463}
4464
4465template<typename BasicJsonType, typename... Args, std::size_t... Idx>
4466std::tuple<Args...> from_json_tuple_impl_base(BasicJsonType&& j, index_sequence<Idx...> /*unused*/)
4467{
4468 return std::make_tuple(std::forward<BasicJsonType>(j).at(Idx).template get<Args>()...);
4469}
4470
4471template < typename BasicJsonType, class A1, class A2 >
4472std::pair<A1, A2> from_json_tuple_impl(BasicJsonType&& j, identity_tag<std::pair<A1, A2>> /*unused*/, priority_tag<0> /*unused*/)
4473{
4474 return {std::forward<BasicJsonType>(j).at(0).template get<A1>(),
4475 std::forward<BasicJsonType>(j).at(1).template get<A2>()};
4476}
4477
4478template<typename BasicJsonType, typename A1, typename A2>
4479void from_json_tuple_impl(BasicJsonType&& j, std::pair<A1, A2>& p, priority_tag<1> /*unused*/)
4480{
4481 p = from_json_tuple_impl(std::forward<BasicJsonType>(j), identity_tag<std::pair<A1, A2>> {}, priority_tag<0> {});
4482}
4483
4484template<typename BasicJsonType, typename... Args>
4485std::tuple<Args...> from_json_tuple_impl(BasicJsonType&& j, identity_tag<std::tuple<Args...>> /*unused*/, priority_tag<2> /*unused*/)
4486{
4487 return from_json_tuple_impl_base<BasicJsonType, Args...>(std::forward<BasicJsonType>(j), index_sequence_for<Args...> {});
4488}
4489
4490template<typename BasicJsonType, typename... Args>
4491void from_json_tuple_impl(BasicJsonType&& j, std::tuple<Args...>& t, priority_tag<3> /*unused*/)
4492{
4493 t = from_json_tuple_impl_base<BasicJsonType, Args...>(std::forward<BasicJsonType>(j), index_sequence_for<Args...> {});
4494}
4495
4496template<typename BasicJsonType, typename TupleRelated>
4497auto from_json(BasicJsonType&& j, TupleRelated&& t)
4498-> decltype(from_json_tuple_impl(std::forward<BasicJsonType>(j), std::forward<TupleRelated>(t), priority_tag<3> {}))
4499{
4500 if (JSON_HEDLEY_UNLIKELY(!j.is_array()))
4501 {
4502 JSON_THROW(type_error::create(302, concat("type must be array, but is ", j.type_name()), &j));
4503 }
4504
4505 return from_json_tuple_impl(std::forward<BasicJsonType>(j), std::forward<TupleRelated>(t), priority_tag<3> {});
4506}
4507
4508template < typename BasicJsonType, typename Key, typename Value, typename Compare, typename Allocator,
4509 typename = enable_if_t < !std::is_constructible <
4510 typename BasicJsonType::string_t, Key >::value >>
4511void from_json(const BasicJsonType& j, std::map<Key, Value, Compare, Allocator>& m)
4512{
4513 if (JSON_HEDLEY_UNLIKELY(!j.is_array()))
4514 {
4515 JSON_THROW(type_error::create(302, concat("type must be array, but is ", j.type_name()), &j));
4516 }
4517 m.clear();
4518 for (const auto& p : j)
4519 {
4520 if (JSON_HEDLEY_UNLIKELY(!p.is_array()))
4521 {
4522 JSON_THROW(type_error::create(302, concat("type must be array, but is ", p.type_name()), &j));
4523 }
4524 m.emplace(p.at(0).template get<Key>(), p.at(1).template get<Value>());
4525 }
4526}
4527
4528template < typename BasicJsonType, typename Key, typename Value, typename Hash, typename KeyEqual, typename Allocator,
4529 typename = enable_if_t < !std::is_constructible <
4530 typename BasicJsonType::string_t, Key >::value >>
4531void from_json(const BasicJsonType& j, std::unordered_map<Key, Value, Hash, KeyEqual, Allocator>& m)
4532{
4533 if (JSON_HEDLEY_UNLIKELY(!j.is_array()))
4534 {
4535 JSON_THROW(type_error::create(302, concat("type must be array, but is ", j.type_name()), &j));
4536 }
4537 m.clear();
4538 for (const auto& p : j)
4539 {
4540 if (JSON_HEDLEY_UNLIKELY(!p.is_array()))
4541 {
4542 JSON_THROW(type_error::create(302, concat("type must be array, but is ", p.type_name()), &j));
4543 }
4544 m.emplace(p.at(0).template get<Key>(), p.at(1).template get<Value>());
4545 }
4546}
4547
4548#if JSON_HAS_FILESYSTEM || JSON_HAS_EXPERIMENTAL_FILESYSTEM
4549template<typename BasicJsonType>
4550void from_json(const BasicJsonType& j, std_fs::path& p)
4551{
4552 if (JSON_HEDLEY_UNLIKELY(!j.is_string()))
4553 {
4554 JSON_THROW(type_error::create(302, concat("type must be string, but is ", j.type_name()), &j));
4555 }
4556 p = *j.template get_ptr<const typename BasicJsonType::string_t*>();
4557}
4558#endif
4559
4560struct from_json_fn
4561{
4562 template<typename BasicJsonType, typename T>
4563 auto operator()(const BasicJsonType& j, T&& val) const
4564 noexcept(noexcept(from_json(j, std::forward<T>(val))))
4565 -> decltype(from_json(j, std::forward<T>(val)))
4566 {
4567 return from_json(j, std::forward<T>(val));
4568 }
4569};
4570} // namespace detail
4571
4575namespace // NOLINT(cert-dcl59-cpp,fuchsia-header-anon-namespaces,google-build-namespaces)
4576{
4577constexpr const auto& from_json = detail::static_const<detail::from_json_fn>::value; // NOLINT(misc-definitions-in-headers)
4578} // namespace
4579} // namespace nlohmann
4580
4581// #include <nlohmann/detail/conversions/to_json.hpp>
4582
4583
4584#include <algorithm> // copy
4585#include <iterator> // begin, end
4586#include <string> // string
4587#include <tuple> // tuple, get
4588#include <type_traits> // is_same, is_constructible, is_floating_point, is_enum, underlying_type
4589#include <utility> // move, forward, declval, pair
4590#include <valarray> // valarray
4591#include <vector> // vector
4592
4593// #include <nlohmann/detail/macro_scope.hpp>
4594
4595// #include <nlohmann/detail/iterators/iteration_proxy.hpp>
4596
4597
4598#include <cstddef> // size_t
4599#include <iterator> // input_iterator_tag
4600#include <string> // string, to_string
4601#include <tuple> // tuple_size, get, tuple_element
4602#include <utility> // move
4603
4604// #include <nlohmann/detail/meta/type_traits.hpp>
4605
4606// #include <nlohmann/detail/value_t.hpp>
4607
4608
4609namespace nlohmann
4610{
4611namespace detail
4612{
4613template<typename string_type>
4614void int_to_string( string_type& target, std::size_t value )
4615{
4616 // For ADL
4617 using std::to_string;
4618 target = to_string(value);
4619}
4620template<typename IteratorType> class iteration_proxy_value
4621{
4622 public:
4623 using difference_type = std::ptrdiff_t;
4624 using value_type = iteration_proxy_value;
4625 using pointer = value_type * ;
4626 using reference = value_type & ;
4627 using iterator_category = std::input_iterator_tag;
4628 using string_type = typename std::remove_cv< typename std::remove_reference<decltype( std::declval<IteratorType>().key() ) >::type >::type;
4629
4630 private:
4632 IteratorType anchor;
4634 std::size_t array_index = 0;
4636 mutable std::size_t array_index_last = 0;
4638 mutable string_type array_index_str = "0";
4640 const string_type empty_str{};
4641
4642 public:
4643 explicit iteration_proxy_value(IteratorType it) noexcept
4644 : anchor(std::move(it))
4645 {}
4646
4648 iteration_proxy_value& operator*()
4649 {
4650 return *this;
4651 }
4652
4654 iteration_proxy_value& operator++()
4655 {
4656 ++anchor;
4657 ++array_index;
4658
4659 return *this;
4660 }
4661
4663 bool operator==(const iteration_proxy_value& o) const
4664 {
4665 return anchor == o.anchor;
4666 }
4667
4669 bool operator!=(const iteration_proxy_value& o) const
4670 {
4671 return anchor != o.anchor;
4672 }
4673
4675 const string_type& key() const
4676 {
4677 JSON_ASSERT(anchor.m_object != nullptr);
4678
4679 switch (anchor.m_object->type())
4680 {
4681 // use integer array index as key
4682 case value_t::array:
4683 {
4684 if (array_index != array_index_last)
4685 {
4686 int_to_string( array_index_str, array_index );
4687 array_index_last = array_index;
4688 }
4689 return array_index_str;
4690 }
4691
4692 // use key from the object
4693 case value_t::object:
4694 return anchor.key();
4695
4696 // use an empty key for all primitive types
4697 case value_t::null:
4698 case value_t::string:
4699 case value_t::boolean:
4703 case value_t::binary:
4704 case value_t::discarded:
4705 default:
4706 return empty_str;
4707 }
4708 }
4709
4711 typename IteratorType::reference value() const
4712 {
4713 return anchor.value();
4714 }
4715};
4716
4718template<typename IteratorType> class iteration_proxy
4719{
4720 private:
4722 typename IteratorType::reference container;
4723
4724 public:
4726 explicit iteration_proxy(typename IteratorType::reference cont) noexcept
4727 : container(cont) {}
4728
4730 iteration_proxy_value<IteratorType> begin() noexcept
4731 {
4732 return iteration_proxy_value<IteratorType>(container.begin());
4733 }
4734
4736 iteration_proxy_value<IteratorType> end() noexcept
4737 {
4738 return iteration_proxy_value<IteratorType>(container.end());
4739 }
4740};
4741// Structured Bindings Support
4742// For further reference see https://blog.tartanllama.xyz/structured-bindings/
4743// And see https://github.com/nlohmann/json/pull/1391
4744template<std::size_t N, typename IteratorType, enable_if_t<N == 0, int> = 0>
4745auto get(const nlohmann::detail::iteration_proxy_value<IteratorType>& i) -> decltype(i.key())
4746{
4747 return i.key();
4748}
4749// Structured Bindings Support
4750// For further reference see https://blog.tartanllama.xyz/structured-bindings/
4751// And see https://github.com/nlohmann/json/pull/1391
4752template<std::size_t N, typename IteratorType, enable_if_t<N == 1, int> = 0>
4753auto get(const nlohmann::detail::iteration_proxy_value<IteratorType>& i) -> decltype(i.value())
4754{
4755 return i.value();
4756}
4757} // namespace detail
4758} // namespace nlohmann
4759
4760// The Addition to the STD Namespace is required to add
4761// Structured Bindings Support to the iteration_proxy_value class
4762// For further reference see https://blog.tartanllama.xyz/structured-bindings/
4763// And see https://github.com/nlohmann/json/pull/1391
4764namespace std
4765{
4766#if defined(__clang__)
4767 // Fix: https://github.com/nlohmann/json/issues/1401
4768 #pragma clang diagnostic push
4769 #pragma clang diagnostic ignored "-Wmismatched-tags"
4770#endif
4771template<typename IteratorType>
4772class tuple_size<::nlohmann::detail::iteration_proxy_value<IteratorType>>
4773 : public std::integral_constant<std::size_t, 2> {};
4774
4775template<std::size_t N, typename IteratorType>
4776class tuple_element<N, ::nlohmann::detail::iteration_proxy_value<IteratorType >>
4777{
4778 public:
4779 using type = decltype(
4780 get<N>(std::declval <
4781 ::nlohmann::detail::iteration_proxy_value<IteratorType >> ()));
4782};
4783#if defined(__clang__)
4784 #pragma clang diagnostic pop
4785#endif
4786} // namespace std
4787
4788// #include <nlohmann/detail/meta/cpp_future.hpp>
4789
4790// #include <nlohmann/detail/meta/type_traits.hpp>
4791
4792// #include <nlohmann/detail/value_t.hpp>
4793
4794
4795#if JSON_HAS_EXPERIMENTAL_FILESYSTEM
4796#include <experimental/filesystem>
4797namespace nlohmann::detail
4798{
4799namespace std_fs = std::experimental::filesystem;
4800} // namespace nlohmann::detail
4801#elif JSON_HAS_FILESYSTEM
4802#include <filesystem>
4803namespace nlohmann::detail
4804{
4805namespace std_fs = std::filesystem;
4806} // namespace nlohmann::detail
4807#endif
4808
4809namespace nlohmann
4810{
4811namespace detail
4812{
4814// constructors //
4816
4817/*
4818 * Note all external_constructor<>::construct functions need to call
4819 * j.m_value.destroy(j.m_type) to avoid a memory leak in case j contains an
4820 * allocated value (e.g., a string). See bug issue
4821 * https://github.com/nlohmann/json/issues/2865 for more information.
4822 */
4823
4824template<value_t> struct external_constructor;
4825
4826template<>
4828{
4829 template<typename BasicJsonType>
4830 static void construct(BasicJsonType& j, typename BasicJsonType::boolean_t b) noexcept
4831 {
4832 j.m_value.destroy(j.m_type);
4833 j.m_type = value_t::boolean;
4834 j.m_value = b;
4835 j.assert_invariant();
4836 }
4837};
4838
4839template<>
4841{
4842 template<typename BasicJsonType>
4843 static void construct(BasicJsonType& j, const typename BasicJsonType::string_t& s)
4844 {
4845 j.m_value.destroy(j.m_type);
4846 j.m_type = value_t::string;
4847 j.m_value = s;
4848 j.assert_invariant();
4849 }
4850
4851 template<typename BasicJsonType>
4852 static void construct(BasicJsonType& j, typename BasicJsonType::string_t&& s)
4853 {
4854 j.m_value.destroy(j.m_type);
4855 j.m_type = value_t::string;
4856 j.m_value = std::move(s);
4857 j.assert_invariant();
4858 }
4859
4860 template < typename BasicJsonType, typename CompatibleStringType,
4861 enable_if_t < !std::is_same<CompatibleStringType, typename BasicJsonType::string_t>::value,
4862 int > = 0 >
4863 static void construct(BasicJsonType& j, const CompatibleStringType& str)
4864 {
4865 j.m_value.destroy(j.m_type);
4866 j.m_type = value_t::string;
4867 j.m_value.string = j.template create<typename BasicJsonType::string_t>(str);
4868 j.assert_invariant();
4869 }
4870};
4871
4872template<>
4874{
4875 template<typename BasicJsonType>
4876 static void construct(BasicJsonType& j, const typename BasicJsonType::binary_t& b)
4877 {
4878 j.m_value.destroy(j.m_type);
4879 j.m_type = value_t::binary;
4880 j.m_value = typename BasicJsonType::binary_t(b);
4881 j.assert_invariant();
4882 }
4883
4884 template<typename BasicJsonType>
4885 static void construct(BasicJsonType& j, typename BasicJsonType::binary_t&& b)
4886 {
4887 j.m_value.destroy(j.m_type);
4888 j.m_type = value_t::binary;
4889 j.m_value = typename BasicJsonType::binary_t(std::move(b));
4890 j.assert_invariant();
4891 }
4892};
4893
4894template<>
4896{
4897 template<typename BasicJsonType>
4898 static void construct(BasicJsonType& j, typename BasicJsonType::number_float_t val) noexcept
4899 {
4900 j.m_value.destroy(j.m_type);
4901 j.m_type = value_t::number_float;
4902 j.m_value = val;
4903 j.assert_invariant();
4904 }
4905};
4906
4907template<>
4909{
4910 template<typename BasicJsonType>
4911 static void construct(BasicJsonType& j, typename BasicJsonType::number_unsigned_t val) noexcept
4912 {
4913 j.m_value.destroy(j.m_type);
4914 j.m_type = value_t::number_unsigned;
4915 j.m_value = val;
4916 j.assert_invariant();
4917 }
4918};
4919
4920template<>
4922{
4923 template<typename BasicJsonType>
4924 static void construct(BasicJsonType& j, typename BasicJsonType::number_integer_t val) noexcept
4925 {
4926 j.m_value.destroy(j.m_type);
4927 j.m_type = value_t::number_integer;
4928 j.m_value = val;
4929 j.assert_invariant();
4930 }
4931};
4932
4933template<>
4935{
4936 template<typename BasicJsonType>
4937 static void construct(BasicJsonType& j, const typename BasicJsonType::array_t& arr)
4938 {
4939 j.m_value.destroy(j.m_type);
4940 j.m_type = value_t::array;
4941 j.m_value = arr;
4942 j.set_parents();
4943 j.assert_invariant();
4944 }
4945
4946 template<typename BasicJsonType>
4947 static void construct(BasicJsonType& j, typename BasicJsonType::array_t&& arr)
4948 {
4949 j.m_value.destroy(j.m_type);
4950 j.m_type = value_t::array;
4951 j.m_value = std::move(arr);
4952 j.set_parents();
4953 j.assert_invariant();
4954 }
4955
4956 template < typename BasicJsonType, typename CompatibleArrayType,
4957 enable_if_t < !std::is_same<CompatibleArrayType, typename BasicJsonType::array_t>::value,
4958 int > = 0 >
4959 static void construct(BasicJsonType& j, const CompatibleArrayType& arr)
4960 {
4961 using std::begin;
4962 using std::end;
4963
4964 j.m_value.destroy(j.m_type);
4965 j.m_type = value_t::array;
4966 j.m_value.array = j.template create<typename BasicJsonType::array_t>(begin(arr), end(arr));
4967 j.set_parents();
4968 j.assert_invariant();
4969 }
4970
4971 template<typename BasicJsonType>
4972 static void construct(BasicJsonType& j, const std::vector<bool>& arr)
4973 {
4974 j.m_value.destroy(j.m_type);
4975 j.m_type = value_t::array;
4976 j.m_value = value_t::array;
4977 j.m_value.array->reserve(arr.size());
4978 for (const bool x : arr)
4979 {
4980 j.m_value.array->push_back(x);
4981 j.set_parent(j.m_value.array->back());
4982 }
4983 j.assert_invariant();
4984 }
4985
4986 template<typename BasicJsonType, typename T,
4988 static void construct(BasicJsonType& j, const std::valarray<T>& arr)
4989 {
4990 j.m_value.destroy(j.m_type);
4991 j.m_type = value_t::array;
4992 j.m_value = value_t::array;
4993 j.m_value.array->resize(arr.size());
4994 if (arr.size() > 0)
4995 {
4996 std::copy(std::begin(arr), std::end(arr), j.m_value.array->begin());
4997 }
4998 j.set_parents();
4999 j.assert_invariant();
5000 }
5001};
5002
5003template<>
5005{
5006 template<typename BasicJsonType>
5007 static void construct(BasicJsonType& j, const typename BasicJsonType::object_t& obj)
5008 {
5009 j.m_value.destroy(j.m_type);
5010 j.m_type = value_t::object;
5011 j.m_value = obj;
5012 j.set_parents();
5013 j.assert_invariant();
5014 }
5015
5016 template<typename BasicJsonType>
5017 static void construct(BasicJsonType& j, typename BasicJsonType::object_t&& obj)
5018 {
5019 j.m_value.destroy(j.m_type);
5020 j.m_type = value_t::object;
5021 j.m_value = std::move(obj);
5022 j.set_parents();
5023 j.assert_invariant();
5024 }
5025
5026 template < typename BasicJsonType, typename CompatibleObjectType,
5027 enable_if_t < !std::is_same<CompatibleObjectType, typename BasicJsonType::object_t>::value, int > = 0 >
5028 static void construct(BasicJsonType& j, const CompatibleObjectType& obj)
5029 {
5030 using std::begin;
5031 using std::end;
5032
5033 j.m_value.destroy(j.m_type);
5034 j.m_type = value_t::object;
5035 j.m_value.object = j.template create<typename BasicJsonType::object_t>(begin(obj), end(obj));
5036 j.set_parents();
5037 j.assert_invariant();
5038 }
5039};
5040
5042// to_json //
5044
5045template<typename BasicJsonType, typename T,
5046 enable_if_t<std::is_same<T, typename BasicJsonType::boolean_t>::value, int> = 0>
5047void to_json(BasicJsonType& j, T b) noexcept
5048{
5050}
5051
5052template<typename BasicJsonType, typename CompatibleString,
5053 enable_if_t<std::is_constructible<typename BasicJsonType::string_t, CompatibleString>::value, int> = 0>
5054void to_json(BasicJsonType& j, const CompatibleString& s)
5055{
5057}
5058
5059template<typename BasicJsonType>
5060void to_json(BasicJsonType& j, typename BasicJsonType::string_t&& s)
5061{
5063}
5064
5065template<typename BasicJsonType, typename FloatType,
5066 enable_if_t<std::is_floating_point<FloatType>::value, int> = 0>
5067void to_json(BasicJsonType& j, FloatType val) noexcept
5068{
5069 external_constructor<value_t::number_float>::construct(j, static_cast<typename BasicJsonType::number_float_t>(val));
5070}
5071
5072template<typename BasicJsonType, typename CompatibleNumberUnsignedType,
5073 enable_if_t<is_compatible_integer_type<typename BasicJsonType::number_unsigned_t, CompatibleNumberUnsignedType>::value, int> = 0>
5074void to_json(BasicJsonType& j, CompatibleNumberUnsignedType val) noexcept
5075{
5076 external_constructor<value_t::number_unsigned>::construct(j, static_cast<typename BasicJsonType::number_unsigned_t>(val));
5077}
5078
5079template<typename BasicJsonType, typename CompatibleNumberIntegerType,
5080 enable_if_t<is_compatible_integer_type<typename BasicJsonType::number_integer_t, CompatibleNumberIntegerType>::value, int> = 0>
5081void to_json(BasicJsonType& j, CompatibleNumberIntegerType val) noexcept
5082{
5083 external_constructor<value_t::number_integer>::construct(j, static_cast<typename BasicJsonType::number_integer_t>(val));
5084}
5085
5086template<typename BasicJsonType, typename EnumType,
5087 enable_if_t<std::is_enum<EnumType>::value, int> = 0>
5088void to_json(BasicJsonType& j, EnumType e) noexcept
5089{
5090 using underlying_type = typename std::underlying_type<EnumType>::type;
5091 external_constructor<value_t::number_integer>::construct(j, static_cast<underlying_type>(e));
5092}
5093
5094template<typename BasicJsonType>
5095void to_json(BasicJsonType& j, const std::vector<bool>& e)
5096{
5098}
5099
5100template < typename BasicJsonType, typename CompatibleArrayType,
5101 enable_if_t < is_compatible_array_type<BasicJsonType,
5102 CompatibleArrayType>::value&&
5103 !is_compatible_object_type<BasicJsonType, CompatibleArrayType>::value&&
5105 !std::is_same<typename BasicJsonType::binary_t, CompatibleArrayType>::value&&
5106 !is_basic_json<CompatibleArrayType>::value,
5107 int > = 0 >
5108void to_json(BasicJsonType& j, const CompatibleArrayType& arr)
5109{
5111}
5112
5113template<typename BasicJsonType>
5114void to_json(BasicJsonType& j, const typename BasicJsonType::binary_t& bin)
5115{
5117}
5118
5119template<typename BasicJsonType, typename T,
5120 enable_if_t<std::is_convertible<T, BasicJsonType>::value, int> = 0>
5121void to_json(BasicJsonType& j, const std::valarray<T>& arr)
5122{
5124}
5125
5126template<typename BasicJsonType>
5127void to_json(BasicJsonType& j, typename BasicJsonType::array_t&& arr)
5128{
5130}
5131
5132template < typename BasicJsonType, typename CompatibleObjectType,
5133 enable_if_t < is_compatible_object_type<BasicJsonType, CompatibleObjectType>::value&& !is_basic_json<CompatibleObjectType>::value, int > = 0 >
5134void to_json(BasicJsonType& j, const CompatibleObjectType& obj)
5135{
5137}
5138
5139template<typename BasicJsonType>
5140void to_json(BasicJsonType& j, typename BasicJsonType::object_t&& obj)
5141{
5143}
5144
5145template <
5146 typename BasicJsonType, typename T, std::size_t N,
5147 enable_if_t < !std::is_constructible<typename BasicJsonType::string_t,
5148 const T(&)[N]>::value, // NOLINT(cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays)
5149 int > = 0 >
5150void to_json(BasicJsonType& j, const T(&arr)[N]) // NOLINT(cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays)
5151{
5153}
5154
5155template < typename BasicJsonType, typename T1, typename T2, enable_if_t < std::is_constructible<BasicJsonType, T1>::value&& std::is_constructible<BasicJsonType, T2>::value, int > = 0 >
5156void to_json(BasicJsonType& j, const std::pair<T1, T2>& p)
5157{
5158 j = { p.first, p.second };
5159}
5160
5161// for https://github.com/nlohmann/json/pull/1134
5162template<typename BasicJsonType, typename T,
5163 enable_if_t<std::is_same<T, iteration_proxy_value<typename BasicJsonType::iterator>>::value, int> = 0>
5164void to_json(BasicJsonType& j, const T& b)
5165{
5166 j = { {b.key(), b.value()} };
5167}
5168
5169template<typename BasicJsonType, typename Tuple, std::size_t... Idx>
5170void to_json_tuple_impl(BasicJsonType& j, const Tuple& t, index_sequence<Idx...> /*unused*/)
5171{
5172 j = { std::get<Idx>(t)... };
5173}
5174
5175template<typename BasicJsonType, typename T, enable_if_t<is_constructible_tuple<BasicJsonType, T>::value, int > = 0>
5176void to_json(BasicJsonType& j, const T& t)
5177{
5178 to_json_tuple_impl(j, t, make_index_sequence<std::tuple_size<T>::value> {});
5179}
5180
5181#if JSON_HAS_FILESYSTEM || JSON_HAS_EXPERIMENTAL_FILESYSTEM
5182template<typename BasicJsonType>
5183void to_json(BasicJsonType& j, const std_fs::path& p)
5184{
5185 j = p.string();
5186}
5187#endif
5188
5190{
5191 template<typename BasicJsonType, typename T>
5192 auto operator()(BasicJsonType& j, T&& val) const noexcept(noexcept(to_json(j, std::forward<T>(val))))
5193 -> decltype(to_json(j, std::forward<T>(val)), void())
5194 {
5195 return to_json(j, std::forward<T>(val));
5196 }
5197};
5198} // namespace detail
5199
5203namespace // NOLINT(cert-dcl59-cpp,fuchsia-header-anon-namespaces,google-build-namespaces)
5204{
5205constexpr const auto& to_json = detail::static_const<detail::to_json_fn>::value; // NOLINT(misc-definitions-in-headers)
5206} // namespace
5207} // namespace nlohmann
5208
5209// #include <nlohmann/detail/meta/identity_tag.hpp>
5210
5211// #include <nlohmann/detail/meta/type_traits.hpp>
5212
5213
5214namespace nlohmann
5215{
5216
5218template<typename ValueType, typename>
5220{
5223 template<typename BasicJsonType, typename TargetType = ValueType>
5224 static auto from_json(BasicJsonType && j, TargetType& val) noexcept(
5225 noexcept(::nlohmann::from_json(std::forward<BasicJsonType>(j), val)))
5226 -> decltype(::nlohmann::from_json(std::forward<BasicJsonType>(j), val), void())
5227 {
5228 ::nlohmann::from_json(std::forward<BasicJsonType>(j), val);
5229 }
5230
5233 template<typename BasicJsonType, typename TargetType = ValueType>
5234 static auto from_json(BasicJsonType && j) noexcept(
5235 noexcept(::nlohmann::from_json(std::forward<BasicJsonType>(j), detail::identity_tag<TargetType> {})))
5236 -> decltype(::nlohmann::from_json(std::forward<BasicJsonType>(j), detail::identity_tag<TargetType> {}))
5237 {
5238 return ::nlohmann::from_json(std::forward<BasicJsonType>(j), detail::identity_tag<TargetType> {});
5239 }
5240
5243 template<typename BasicJsonType, typename TargetType = ValueType>
5244 static auto to_json(BasicJsonType& j, TargetType && val) noexcept(
5245 noexcept(::nlohmann::to_json(j, std::forward<TargetType>(val))))
5246 -> decltype(::nlohmann::to_json(j, std::forward<TargetType>(val)), void())
5247 {
5248 ::nlohmann::to_json(j, std::forward<TargetType>(val));
5249 }
5250};
5251} // namespace nlohmann
5252
5253// #include <nlohmann/byte_container_with_subtype.hpp>
5254
5255
5256#include <cstdint> // uint8_t, uint64_t
5257#include <tuple> // tie
5258#include <utility> // move
5259
5260namespace nlohmann
5261{
5262
5265template<typename BinaryType>
5266class byte_container_with_subtype : public BinaryType
5267{
5268 public:
5269 using container_type = BinaryType;
5270 using subtype_type = std::uint64_t;
5271
5274 : container_type()
5275 {}
5276
5279 : container_type(b)
5280 {}
5281
5286
5289 : container_type(b)
5290 , m_subtype(subtype_)
5291 , m_has_subtype(true)
5292 {}
5293
5297 , m_subtype(subtype_)
5298 , m_has_subtype(true)
5299 {}
5300
5302 {
5303 return std::tie(static_cast<const BinaryType&>(*this), m_subtype, m_has_subtype) ==
5304 std::tie(static_cast<const BinaryType&>(rhs), rhs.m_subtype, rhs.m_has_subtype);
5305 }
5306
5308 {
5309 return !(rhs == *this);
5310 }
5311
5314 void set_subtype(subtype_type subtype_) noexcept
5315 {
5316 m_subtype = subtype_;
5317 m_has_subtype = true;
5318 }
5319
5322 constexpr subtype_type subtype() const noexcept
5323 {
5324 return m_has_subtype ? m_subtype : static_cast<subtype_type>(-1);
5325 }
5326
5329 constexpr bool has_subtype() const noexcept
5330 {
5331 return m_has_subtype;
5332 }
5333
5336 void clear_subtype() noexcept
5337 {
5338 m_subtype = 0;
5339 m_has_subtype = false;
5340 }
5341
5342 private:
5343 subtype_type m_subtype = 0;
5344 bool m_has_subtype = false;
5345};
5346
5347} // namespace nlohmann
5348
5349// #include <nlohmann/detail/conversions/from_json.hpp>
5350
5351// #include <nlohmann/detail/conversions/to_json.hpp>
5352
5353// #include <nlohmann/detail/exceptions.hpp>
5354
5355// #include <nlohmann/detail/hash.hpp>
5356
5357
5358#include <cstdint> // uint8_t
5359#include <cstddef> // size_t
5360#include <functional> // hash
5361
5362// #include <nlohmann/detail/macro_scope.hpp>
5363
5364// #include <nlohmann/detail/value_t.hpp>
5365
5366
5367namespace nlohmann
5368{
5369namespace detail
5370{
5371
5372// boost::hash_combine
5373inline std::size_t combine(std::size_t seed, std::size_t h) noexcept
5374{
5375 seed ^= h + 0x9e3779b9 + (seed << 6U) + (seed >> 2U);
5376 return seed;
5377}
5378
5390template<typename BasicJsonType>
5391std::size_t hash(const BasicJsonType& j)
5392{
5393 using string_t = typename BasicJsonType::string_t;
5394 using number_integer_t = typename BasicJsonType::number_integer_t;
5395 using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
5396 using number_float_t = typename BasicJsonType::number_float_t;
5397
5398 const auto type = static_cast<std::size_t>(j.type());
5399 switch (j.type())
5400 {
5401 case BasicJsonType::value_t::null:
5402 case BasicJsonType::value_t::discarded:
5403 {
5404 return combine(type, 0);
5405 }
5406
5407 case BasicJsonType::value_t::object:
5408 {
5409 auto seed = combine(type, j.size());
5410 for (const auto& element : j.items())
5411 {
5412 const auto h = std::hash<string_t> {}(element.key());
5413 seed = combine(seed, h);
5414 seed = combine(seed, hash(element.value()));
5415 }
5416 return seed;
5417 }
5418
5419 case BasicJsonType::value_t::array:
5420 {
5421 auto seed = combine(type, j.size());
5422 for (const auto& element : j)
5423 {
5424 seed = combine(seed, hash(element));
5425 }
5426 return seed;
5427 }
5428
5429 case BasicJsonType::value_t::string:
5430 {
5431 const auto h = std::hash<string_t> {}(j.template get_ref<const string_t&>());
5432 return combine(type, h);
5433 }
5434
5435 case BasicJsonType::value_t::boolean:
5436 {
5437 const auto h = std::hash<bool> {}(j.template get<bool>());
5438 return combine(type, h);
5439 }
5440
5441 case BasicJsonType::value_t::number_integer:
5442 {
5443 const auto h = std::hash<number_integer_t> {}(j.template get<number_integer_t>());
5444 return combine(type, h);
5445 }
5446
5447 case BasicJsonType::value_t::number_unsigned:
5448 {
5449 const auto h = std::hash<number_unsigned_t> {}(j.template get<number_unsigned_t>());
5450 return combine(type, h);
5451 }
5452
5453 case BasicJsonType::value_t::number_float:
5454 {
5455 const auto h = std::hash<number_float_t> {}(j.template get<number_float_t>());
5456 return combine(type, h);
5457 }
5458
5459 case BasicJsonType::value_t::binary:
5460 {
5461 auto seed = combine(type, j.get_binary().size());
5462 const auto h = std::hash<bool> {}(j.get_binary().has_subtype());
5463 seed = combine(seed, h);
5464 seed = combine(seed, static_cast<std::size_t>(j.get_binary().subtype()));
5465 for (const auto byte : j.get_binary())
5466 {
5467 seed = combine(seed, std::hash<std::uint8_t> {}(byte));
5468 }
5469 return seed;
5470 }
5471
5472 default: // LCOV_EXCL_LINE
5473 JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert) LCOV_EXCL_LINE
5474 return 0; // LCOV_EXCL_LINE
5475 }
5476}
5477
5478} // namespace detail
5479} // namespace nlohmann
5480
5481// #include <nlohmann/detail/input/binary_reader.hpp>
5482
5483
5484#include <algorithm> // generate_n
5485#include <array> // array
5486#include <cmath> // ldexp
5487#include <cstddef> // size_t
5488#include <cstdint> // uint8_t, uint16_t, uint32_t, uint64_t
5489#include <cstdio> // snprintf
5490#include <cstring> // memcpy
5491#include <iterator> // back_inserter
5492#include <limits> // numeric_limits
5493#include <string> // char_traits, string
5494#include <utility> // make_pair, move
5495#include <vector> // vector
5496#include <map> // map
5497
5498// #include <nlohmann/detail/exceptions.hpp>
5499
5500// #include <nlohmann/detail/input/input_adapters.hpp>
5501
5502
5503#include <array> // array
5504#include <cstddef> // size_t
5505#include <cstring> // strlen
5506#include <iterator> // begin, end, iterator_traits, random_access_iterator_tag, distance, next
5507#include <memory> // shared_ptr, make_shared, addressof
5508#include <numeric> // accumulate
5509#include <string> // string, char_traits
5510#include <type_traits> // enable_if, is_base_of, is_pointer, is_integral, remove_pointer
5511#include <utility> // pair, declval
5512
5513#ifndef JSON_NO_IO
5514 #include <cstdio> // FILE *
5515 #include <istream> // istream
5516#endif // JSON_NO_IO
5517
5518// #include <nlohmann/detail/iterators/iterator_traits.hpp>
5519
5520// #include <nlohmann/detail/macro_scope.hpp>
5521
5522
5523namespace nlohmann
5524{
5525namespace detail
5526{
5528enum class input_format_t { json, cbor, msgpack, ubjson, bson, bjdata };
5529
5531// input adapters //
5533
5534#ifndef JSON_NO_IO
5539class file_input_adapter
5540{
5541 public:
5542 using char_type = char;
5543
5545 explicit file_input_adapter(std::FILE* f) noexcept
5546 : m_file(f)
5547 {}
5548
5549 // make class move-only
5550 file_input_adapter(const file_input_adapter&) = delete;
5551 file_input_adapter(file_input_adapter&&) noexcept = default;
5552 file_input_adapter& operator=(const file_input_adapter&) = delete;
5553 file_input_adapter& operator=(file_input_adapter&&) = delete;
5554 ~file_input_adapter() = default;
5555
5556 std::char_traits<char>::int_type get_character() noexcept
5557 {
5558 return std::fgetc(m_file);
5559 }
5560
5561 private:
5563 std::FILE* m_file;
5564};
5565
5566
5576class input_stream_adapter
5577{
5578 public:
5579 using char_type = char;
5580
5581 ~input_stream_adapter()
5582 {
5583 // clear stream flags; we use underlying streambuf I/O, do not
5584 // maintain ifstream flags, except eof
5585 if (is != nullptr)
5586 {
5587 is->clear(is->rdstate() & std::ios::eofbit);
5588 }
5589 }
5590
5591 explicit input_stream_adapter(std::istream& i)
5592 : is(&i), sb(i.rdbuf())
5593 {}
5594
5595 // delete because of pointer members
5596 input_stream_adapter(const input_stream_adapter&) = delete;
5597 input_stream_adapter& operator=(input_stream_adapter&) = delete;
5598 input_stream_adapter& operator=(input_stream_adapter&&) = delete;
5599
5600 input_stream_adapter(input_stream_adapter&& rhs) noexcept
5601 : is(rhs.is), sb(rhs.sb)
5602 {
5603 rhs.is = nullptr;
5604 rhs.sb = nullptr;
5605 }
5606
5607 // std::istream/std::streambuf use std::char_traits<char>::to_int_type, to
5608 // ensure that std::char_traits<char>::eof() and the character 0xFF do not
5609 // end up as the same value, e.g. 0xFFFFFFFF.
5610 std::char_traits<char>::int_type get_character()
5611 {
5612 auto res = sb->sbumpc();
5613 // set eof manually, as we don't use the istream interface.
5614 if (JSON_HEDLEY_UNLIKELY(res == std::char_traits<char>::eof()))
5615 {
5616 is->clear(is->rdstate() | std::ios::eofbit);
5617 }
5618 return res;
5619 }
5620
5621 private:
5623 std::istream* is = nullptr;
5624 std::streambuf* sb = nullptr;
5625};
5626#endif // JSON_NO_IO
5627
5628// General-purpose iterator-based adapter. It might not be as fast as
5629// theoretically possible for some containers, but it is extremely versatile.
5630template<typename IteratorType>
5631class iterator_input_adapter
5632{
5633 public:
5634 using char_type = typename std::iterator_traits<IteratorType>::value_type;
5635
5636 iterator_input_adapter(IteratorType first, IteratorType last)
5637 : current(std::move(first)), end(std::move(last))
5638 {}
5639
5640 typename std::char_traits<char_type>::int_type get_character()
5641 {
5642 if (JSON_HEDLEY_LIKELY(current != end))
5643 {
5644 auto result = std::char_traits<char_type>::to_int_type(*current);
5645 std::advance(current, 1);
5646 return result;
5647 }
5648
5649 return std::char_traits<char_type>::eof();
5650 }
5651
5652 private:
5653 IteratorType current;
5654 IteratorType end;
5655
5656 template<typename BaseInputAdapter, size_t T>
5657 friend struct wide_string_input_helper;
5658
5659 bool empty() const
5660 {
5661 return current == end;
5662 }
5663};
5664
5665
5666template<typename BaseInputAdapter, size_t T>
5667struct wide_string_input_helper;
5668
5669template<typename BaseInputAdapter>
5670struct wide_string_input_helper<BaseInputAdapter, 4>
5671{
5672 // UTF-32
5673 static void fill_buffer(BaseInputAdapter& input,
5674 std::array<std::char_traits<char>::int_type, 4>& utf8_bytes,
5675 size_t& utf8_bytes_index,
5676 size_t& utf8_bytes_filled)
5677 {
5678 utf8_bytes_index = 0;
5679
5680 if (JSON_HEDLEY_UNLIKELY(input.empty()))
5681 {
5682 utf8_bytes[0] = std::char_traits<char>::eof();
5683 utf8_bytes_filled = 1;
5684 }
5685 else
5686 {
5687 // get the current character
5688 const auto wc = input.get_character();
5689
5690 // UTF-32 to UTF-8 encoding
5691 if (wc < 0x80)
5692 {
5693 utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(wc);
5694 utf8_bytes_filled = 1;
5695 }
5696 else if (wc <= 0x7FF)
5697 {
5698 utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(0xC0u | ((static_cast<unsigned int>(wc) >> 6u) & 0x1Fu));
5699 utf8_bytes[1] = static_cast<std::char_traits<char>::int_type>(0x80u | (static_cast<unsigned int>(wc) & 0x3Fu));
5700 utf8_bytes_filled = 2;
5701 }
5702 else if (wc <= 0xFFFF)
5703 {
5704 utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(0xE0u | ((static_cast<unsigned int>(wc) >> 12u) & 0x0Fu));
5705 utf8_bytes[1] = static_cast<std::char_traits<char>::int_type>(0x80u | ((static_cast<unsigned int>(wc) >> 6u) & 0x3Fu));
5706 utf8_bytes[2] = static_cast<std::char_traits<char>::int_type>(0x80u | (static_cast<unsigned int>(wc) & 0x3Fu));
5707 utf8_bytes_filled = 3;
5708 }
5709 else if (wc <= 0x10FFFF)
5710 {
5711 utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(0xF0u | ((static_cast<unsigned int>(wc) >> 18u) & 0x07u));
5712 utf8_bytes[1] = static_cast<std::char_traits<char>::int_type>(0x80u | ((static_cast<unsigned int>(wc) >> 12u) & 0x3Fu));
5713 utf8_bytes[2] = static_cast<std::char_traits<char>::int_type>(0x80u | ((static_cast<unsigned int>(wc) >> 6u) & 0x3Fu));
5714 utf8_bytes[3] = static_cast<std::char_traits<char>::int_type>(0x80u | (static_cast<unsigned int>(wc) & 0x3Fu));
5715 utf8_bytes_filled = 4;
5716 }
5717 else
5718 {
5719 // unknown character
5720 utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(wc);
5721 utf8_bytes_filled = 1;
5722 }
5723 }
5724 }
5725};
5726
5727template<typename BaseInputAdapter>
5728struct wide_string_input_helper<BaseInputAdapter, 2>
5729{
5730 // UTF-16
5731 static void fill_buffer(BaseInputAdapter& input,
5732 std::array<std::char_traits<char>::int_type, 4>& utf8_bytes,
5733 size_t& utf8_bytes_index,
5734 size_t& utf8_bytes_filled)
5735 {
5736 utf8_bytes_index = 0;
5737
5738 if (JSON_HEDLEY_UNLIKELY(input.empty()))
5739 {
5740 utf8_bytes[0] = std::char_traits<char>::eof();
5741 utf8_bytes_filled = 1;
5742 }
5743 else
5744 {
5745 // get the current character
5746 const auto wc = input.get_character();
5747
5748 // UTF-16 to UTF-8 encoding
5749 if (wc < 0x80)
5750 {
5751 utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(wc);
5752 utf8_bytes_filled = 1;
5753 }
5754 else if (wc <= 0x7FF)
5755 {
5756 utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(0xC0u | ((static_cast<unsigned int>(wc) >> 6u)));
5757 utf8_bytes[1] = static_cast<std::char_traits<char>::int_type>(0x80u | (static_cast<unsigned int>(wc) & 0x3Fu));
5758 utf8_bytes_filled = 2;
5759 }
5760 else if (0xD800 > wc || wc >= 0xE000)
5761 {
5762 utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(0xE0u | ((static_cast<unsigned int>(wc) >> 12u)));
5763 utf8_bytes[1] = static_cast<std::char_traits<char>::int_type>(0x80u | ((static_cast<unsigned int>(wc) >> 6u) & 0x3Fu));
5764 utf8_bytes[2] = static_cast<std::char_traits<char>::int_type>(0x80u | (static_cast<unsigned int>(wc) & 0x3Fu));
5765 utf8_bytes_filled = 3;
5766 }
5767 else
5768 {
5769 if (JSON_HEDLEY_UNLIKELY(!input.empty()))
5770 {
5771 const auto wc2 = static_cast<unsigned int>(input.get_character());
5772 const auto charcode = 0x10000u + (((static_cast<unsigned int>(wc) & 0x3FFu) << 10u) | (wc2 & 0x3FFu));
5773 utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(0xF0u | (charcode >> 18u));
5774 utf8_bytes[1] = static_cast<std::char_traits<char>::int_type>(0x80u | ((charcode >> 12u) & 0x3Fu));
5775 utf8_bytes[2] = static_cast<std::char_traits<char>::int_type>(0x80u | ((charcode >> 6u) & 0x3Fu));
5776 utf8_bytes[3] = static_cast<std::char_traits<char>::int_type>(0x80u | (charcode & 0x3Fu));
5777 utf8_bytes_filled = 4;
5778 }
5779 else
5780 {
5781 utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(wc);
5782 utf8_bytes_filled = 1;
5783 }
5784 }
5785 }
5786 }
5787};
5788
5789// Wraps another input apdater to convert wide character types into individual bytes.
5790template<typename BaseInputAdapter, typename WideCharType>
5791class wide_string_input_adapter
5792{
5793 public:
5794 using char_type = char;
5795
5796 wide_string_input_adapter(BaseInputAdapter base)
5797 : base_adapter(base) {}
5798
5799 typename std::char_traits<char>::int_type get_character() noexcept
5800 {
5801 // check if buffer needs to be filled
5802 if (utf8_bytes_index == utf8_bytes_filled)
5803 {
5804 fill_buffer<sizeof(WideCharType)>();
5805
5806 JSON_ASSERT(utf8_bytes_filled > 0);
5807 JSON_ASSERT(utf8_bytes_index == 0);
5808 }
5809
5810 // use buffer
5811 JSON_ASSERT(utf8_bytes_filled > 0);
5812 JSON_ASSERT(utf8_bytes_index < utf8_bytes_filled);
5813 return utf8_bytes[utf8_bytes_index++];
5814 }
5815
5816 private:
5817 BaseInputAdapter base_adapter;
5818
5819 template<size_t T>
5820 void fill_buffer()
5821 {
5822 wide_string_input_helper<BaseInputAdapter, T>::fill_buffer(base_adapter, utf8_bytes, utf8_bytes_index, utf8_bytes_filled);
5823 }
5824
5826 std::array<std::char_traits<char>::int_type, 4> utf8_bytes = {{0, 0, 0, 0}};
5827
5829 std::size_t utf8_bytes_index = 0;
5831 std::size_t utf8_bytes_filled = 0;
5832};
5833
5834
5835template<typename IteratorType, typename Enable = void>
5836struct iterator_input_adapter_factory
5837{
5838 using iterator_type = IteratorType;
5839 using char_type = typename std::iterator_traits<iterator_type>::value_type;
5840 using adapter_type = iterator_input_adapter<iterator_type>;
5841
5842 static adapter_type create(IteratorType first, IteratorType last)
5843 {
5844 return adapter_type(std::move(first), std::move(last));
5845 }
5846};
5847
5848template<typename T>
5849struct is_iterator_of_multibyte
5850{
5851 using value_type = typename std::iterator_traits<T>::value_type;
5852 enum
5853 {
5854 value = sizeof(value_type) > 1
5855 };
5856};
5857
5858template<typename IteratorType>
5859struct iterator_input_adapter_factory<IteratorType, enable_if_t<is_iterator_of_multibyte<IteratorType>::value>>
5860{
5861 using iterator_type = IteratorType;
5862 using char_type = typename std::iterator_traits<iterator_type>::value_type;
5863 using base_adapter_type = iterator_input_adapter<iterator_type>;
5864 using adapter_type = wide_string_input_adapter<base_adapter_type, char_type>;
5865
5866 static adapter_type create(IteratorType first, IteratorType last)
5867 {
5868 return adapter_type(base_adapter_type(std::move(first), std::move(last)));
5869 }
5870};
5871
5872// General purpose iterator-based input
5873template<typename IteratorType>
5874typename iterator_input_adapter_factory<IteratorType>::adapter_type input_adapter(IteratorType first, IteratorType last)
5875{
5876 using factory_type = iterator_input_adapter_factory<IteratorType>;
5877 return factory_type::create(first, last);
5878}
5879
5880// Convenience shorthand from container to iterator
5881// Enables ADL on begin(container) and end(container)
5882// Encloses the using declarations in namespace for not to leak them to outside scope
5883
5884namespace container_input_adapter_factory_impl
5885{
5886
5887using std::begin;
5888using std::end;
5889
5890template<typename ContainerType, typename Enable = void>
5892
5893template<typename ContainerType>
5895 void_t<decltype(begin(std::declval<ContainerType>()), end(std::declval<ContainerType>()))>>
5896 {
5897 using adapter_type = decltype(input_adapter(begin(std::declval<ContainerType>()), end(std::declval<ContainerType>())));
5898
5899 static adapter_type create(const ContainerType& container)
5900{
5901 return input_adapter(begin(container), end(container));
5902}
5903 };
5904
5905} // namespace container_input_adapter_factory_impl
5906
5907template<typename ContainerType>
5908typename container_input_adapter_factory_impl::container_input_adapter_factory<ContainerType>::adapter_type input_adapter(const ContainerType& container)
5909{
5910 return container_input_adapter_factory_impl::container_input_adapter_factory<ContainerType>::create(container);
5911}
5912
5913#ifndef JSON_NO_IO
5914// Special cases with fast paths
5915inline file_input_adapter input_adapter(std::FILE* file)
5916{
5917 return file_input_adapter(file);
5918}
5919
5920inline input_stream_adapter input_adapter(std::istream& stream)
5921{
5922 return input_stream_adapter(stream);
5923}
5924
5925inline input_stream_adapter input_adapter(std::istream&& stream)
5926{
5927 return input_stream_adapter(stream);
5928}
5929#endif // JSON_NO_IO
5930
5931using contiguous_bytes_input_adapter = decltype(input_adapter(std::declval<const char*>(), std::declval<const char*>()));
5932
5933// Null-delimited strings, and the like.
5934template < typename CharT,
5935 typename std::enable_if <
5936 std::is_pointer<CharT>::value&&
5937 !std::is_array<CharT>::value&&
5938 std::is_integral<typename std::remove_pointer<CharT>::type>::value&&
5939 sizeof(typename std::remove_pointer<CharT>::type) == 1,
5940 int >::type = 0 >
5941contiguous_bytes_input_adapter input_adapter(CharT b)
5942{
5943 auto length = std::strlen(reinterpret_cast<const char*>(b));
5944 const auto* ptr = reinterpret_cast<const char*>(b);
5945 return input_adapter(ptr, ptr + length);
5946}
5947
5948template<typename T, std::size_t N>
5949auto input_adapter(T (&array)[N]) -> decltype(input_adapter(array, array + N)) // NOLINT(cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays)
5950{
5951 return input_adapter(array, array + N);
5952}
5953
5954// This class only handles inputs of input_buffer_adapter type.
5955// It's required so that expressions like {ptr, len} can be implicitly cast
5956// to the correct adapter.
5957class span_input_adapter
5958{
5959 public:
5960 template < typename CharT,
5961 typename std::enable_if <
5962 std::is_pointer<CharT>::value&&
5963 std::is_integral<typename std::remove_pointer<CharT>::type>::value&&
5964 sizeof(typename std::remove_pointer<CharT>::type) == 1,
5965 int >::type = 0 >
5966 span_input_adapter(CharT b, std::size_t l)
5967 : ia(reinterpret_cast<const char*>(b), reinterpret_cast<const char*>(b) + l) {}
5968
5969 template<class IteratorType,
5970 typename std::enable_if<
5971 std::is_same<typename iterator_traits<IteratorType>::iterator_category, std::random_access_iterator_tag>::value,
5972 int>::type = 0>
5973 span_input_adapter(IteratorType first, IteratorType last)
5974 : ia(input_adapter(first, last)) {}
5975
5976 contiguous_bytes_input_adapter&& get()
5977 {
5978 return std::move(ia); // NOLINT(hicpp-move-const-arg,performance-move-const-arg)
5979 }
5980
5981 private:
5982 contiguous_bytes_input_adapter ia;
5983};
5984} // namespace detail
5985} // namespace nlohmann
5986
5987// #include <nlohmann/detail/input/json_sax.hpp>
5988
5989
5990#include <cstddef>
5991#include <string> // string
5992#include <utility> // move
5993#include <vector> // vector
5994
5995// #include <nlohmann/detail/exceptions.hpp>
5996
5997// #include <nlohmann/detail/macro_scope.hpp>
5998
5999// #include <nlohmann/detail/string_concat.hpp>
6000
6001
6002namespace nlohmann
6003{
6004
6013template<typename BasicJsonType>
6014struct json_sax
6015{
6016 using number_integer_t = typename BasicJsonType::number_integer_t;
6017 using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
6018 using number_float_t = typename BasicJsonType::number_float_t;
6019 using string_t = typename BasicJsonType::string_t;
6020 using binary_t = typename BasicJsonType::binary_t;
6021
6026 virtual bool null() = 0;
6027
6033 virtual bool boolean(bool val) = 0;
6034
6040 virtual bool number_integer(number_integer_t val) = 0;
6041
6047 virtual bool number_unsigned(number_unsigned_t val) = 0;
6048
6055 virtual bool number_float(number_float_t val, const string_t& s) = 0;
6056
6063 virtual bool string(string_t& val) = 0;
6064
6071 virtual bool binary(binary_t& val) = 0;
6072
6079 virtual bool start_object(std::size_t elements) = 0;
6080
6087 virtual bool key(string_t& val) = 0;
6088
6093 virtual bool end_object() = 0;
6094
6101 virtual bool start_array(std::size_t elements) = 0;
6102
6107 virtual bool end_array() = 0;
6108
6116 virtual bool parse_error(std::size_t position,
6117 const std::string& last_token,
6118 const detail::exception& ex) = 0;
6119
6120 json_sax() = default;
6121 json_sax(const json_sax&) = default;
6122 json_sax(json_sax&&) noexcept = default;
6123 json_sax& operator=(const json_sax&) = default;
6124 json_sax& operator=(json_sax&&) noexcept = default;
6125 virtual ~json_sax() = default;
6126};
6127
6128
6129namespace detail
6130{
6144template<typename BasicJsonType>
6146{
6147 public:
6148 using number_integer_t = typename BasicJsonType::number_integer_t;
6149 using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
6150 using number_float_t = typename BasicJsonType::number_float_t;
6151 using string_t = typename BasicJsonType::string_t;
6152 using binary_t = typename BasicJsonType::binary_t;
6153
6159 explicit json_sax_dom_parser(BasicJsonType& r, const bool allow_exceptions_ = true)
6160 : root(r), allow_exceptions(allow_exceptions_)
6161 {}
6162
6163 // make class move-only
6165 json_sax_dom_parser(json_sax_dom_parser&&) = default; // NOLINT(hicpp-noexcept-move,performance-noexcept-move-constructor)
6167 json_sax_dom_parser& operator=(json_sax_dom_parser&&) = default; // NOLINT(hicpp-noexcept-move,performance-noexcept-move-constructor)
6169
6170 bool null()
6171 {
6172 handle_value(nullptr);
6173 return true;
6174 }
6175
6176 bool boolean(bool val)
6177 {
6178 handle_value(val);
6179 return true;
6180 }
6181
6183 {
6184 handle_value(val);
6185 return true;
6186 }
6187
6189 {
6190 handle_value(val);
6191 return true;
6192 }
6193
6194 bool number_float(number_float_t val, const string_t& /*unused*/)
6195 {
6196 handle_value(val);
6197 return true;
6198 }
6199
6201 {
6202 handle_value(val);
6203 return true;
6204 }
6205
6207 {
6208 handle_value(std::move(val));
6209 return true;
6210 }
6211
6212 bool start_object(std::size_t len)
6213 {
6214 ref_stack.push_back(handle_value(BasicJsonType::value_t::object));
6215
6216 if (JSON_HEDLEY_UNLIKELY(len != static_cast<std::size_t>(-1) && len > ref_stack.back()->max_size()))
6217 {
6218 JSON_THROW(out_of_range::create(408, concat("excessive object size: ", std::to_string(len)), ref_stack.back()));
6219 }
6220
6221 return true;
6222 }
6223
6225 {
6226 // add null at given key and store the reference for later
6227 object_element = &(ref_stack.back()->m_value.object->operator[](val));
6228 return true;
6229 }
6230
6232 {
6233 ref_stack.back()->set_parents();
6234 ref_stack.pop_back();
6235 return true;
6236 }
6237
6238 bool start_array(std::size_t len)
6239 {
6240 ref_stack.push_back(handle_value(BasicJsonType::value_t::array));
6241
6242 if (JSON_HEDLEY_UNLIKELY(len != static_cast<std::size_t>(-1) && len > ref_stack.back()->max_size()))
6243 {
6244 JSON_THROW(out_of_range::create(408, concat("excessive array size: ", std::to_string(len)), ref_stack.back()));
6245 }
6246
6247 return true;
6248 }
6249
6251 {
6252 ref_stack.back()->set_parents();
6253 ref_stack.pop_back();
6254 return true;
6255 }
6256
6257 template<class Exception>
6258 bool parse_error(std::size_t /*unused*/, const std::string& /*unused*/,
6259 const Exception& ex)
6260 {
6261 errored = true;
6262 static_cast<void>(ex);
6263 if (allow_exceptions)
6264 {
6265 JSON_THROW(ex);
6266 }
6267 return false;
6268 }
6269
6270 constexpr bool is_errored() const
6271 {
6272 return errored;
6273 }
6274
6275 private:
6282 template<typename Value>
6284 BasicJsonType* handle_value(Value&& v)
6285 {
6286 if (ref_stack.empty())
6287 {
6288 root = BasicJsonType(std::forward<Value>(v));
6289 return &root;
6290 }
6291
6292 JSON_ASSERT(ref_stack.back()->is_array() || ref_stack.back()->is_object());
6293
6294 if (ref_stack.back()->is_array())
6295 {
6296 ref_stack.back()->m_value.array->emplace_back(std::forward<Value>(v));
6297 return &(ref_stack.back()->m_value.array->back());
6298 }
6299
6300 JSON_ASSERT(ref_stack.back()->is_object());
6301 JSON_ASSERT(object_element);
6302 *object_element = BasicJsonType(std::forward<Value>(v));
6303 return object_element;
6304 }
6305
6307 BasicJsonType& root;
6309 std::vector<BasicJsonType*> ref_stack {};
6311 BasicJsonType* object_element = nullptr;
6313 bool errored = false;
6315 const bool allow_exceptions = true;
6316};
6317
6318template<typename BasicJsonType>
6320{
6321 public:
6322 using number_integer_t = typename BasicJsonType::number_integer_t;
6323 using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
6324 using number_float_t = typename BasicJsonType::number_float_t;
6325 using string_t = typename BasicJsonType::string_t;
6326 using binary_t = typename BasicJsonType::binary_t;
6327 using parser_callback_t = typename BasicJsonType::parser_callback_t;
6328 using parse_event_t = typename BasicJsonType::parse_event_t;
6329
6331 const parser_callback_t cb,
6332 const bool allow_exceptions_ = true)
6333 : root(r), callback(cb), allow_exceptions(allow_exceptions_)
6334 {
6335 keep_stack.push_back(true);
6336 }
6337
6338 // make class move-only
6340 json_sax_dom_callback_parser(json_sax_dom_callback_parser&&) = default; // NOLINT(hicpp-noexcept-move,performance-noexcept-move-constructor)
6342 json_sax_dom_callback_parser& operator=(json_sax_dom_callback_parser&&) = default; // NOLINT(hicpp-noexcept-move,performance-noexcept-move-constructor)
6344
6345 bool null()
6346 {
6347 handle_value(nullptr);
6348 return true;
6349 }
6350
6351 bool boolean(bool val)
6352 {
6353 handle_value(val);
6354 return true;
6355 }
6356
6358 {
6359 handle_value(val);
6360 return true;
6361 }
6362
6364 {
6365 handle_value(val);
6366 return true;
6367 }
6368
6369 bool number_float(number_float_t val, const string_t& /*unused*/)
6370 {
6371 handle_value(val);
6372 return true;
6373 }
6374
6376 {
6377 handle_value(val);
6378 return true;
6379 }
6380
6382 {
6383 handle_value(std::move(val));
6384 return true;
6385 }
6386
6387 bool start_object(std::size_t len)
6388 {
6389 // check callback for object start
6390 const bool keep = callback(static_cast<int>(ref_stack.size()), parse_event_t::object_start, discarded);
6391 keep_stack.push_back(keep);
6392
6393 auto val = handle_value(BasicJsonType::value_t::object, true);
6394 ref_stack.push_back(val.second);
6395
6396 // check object limit
6397 if (ref_stack.back() && JSON_HEDLEY_UNLIKELY(len != static_cast<std::size_t>(-1) && len > ref_stack.back()->max_size()))
6398 {
6399 JSON_THROW(out_of_range::create(408, concat("excessive object size: ", std::to_string(len)), ref_stack.back()));
6400 }
6401
6402 return true;
6403 }
6404
6406 {
6407 BasicJsonType k = BasicJsonType(val);
6408
6409 // check callback for key
6410 const bool keep = callback(static_cast<int>(ref_stack.size()), parse_event_t::key, k);
6411 key_keep_stack.push_back(keep);
6412
6413 // add discarded value at given key and store the reference for later
6414 if (keep && ref_stack.back())
6415 {
6416 object_element = &(ref_stack.back()->m_value.object->operator[](val) = discarded);
6417 }
6418
6419 return true;
6420 }
6421
6423 {
6424 if (ref_stack.back())
6425 {
6426 if (!callback(static_cast<int>(ref_stack.size()) - 1, parse_event_t::object_end, *ref_stack.back()))
6427 {
6428 // discard object
6429 *ref_stack.back() = discarded;
6430 }
6431 else
6432 {
6433 ref_stack.back()->set_parents();
6434 }
6435 }
6436
6437 JSON_ASSERT(!ref_stack.empty());
6438 JSON_ASSERT(!keep_stack.empty());
6439 ref_stack.pop_back();
6440 keep_stack.pop_back();
6441
6442 if (!ref_stack.empty() && ref_stack.back() && ref_stack.back()->is_structured())
6443 {
6444 // remove discarded value
6445 for (auto it = ref_stack.back()->begin(); it != ref_stack.back()->end(); ++it)
6446 {
6447 if (it->is_discarded())
6448 {
6449 ref_stack.back()->erase(it);
6450 break;
6451 }
6452 }
6453 }
6454
6455 return true;
6456 }
6457
6458 bool start_array(std::size_t len)
6459 {
6460 const bool keep = callback(static_cast<int>(ref_stack.size()), parse_event_t::array_start, discarded);
6461 keep_stack.push_back(keep);
6462
6463 auto val = handle_value(BasicJsonType::value_t::array, true);
6464 ref_stack.push_back(val.second);
6465
6466 // check array limit
6467 if (ref_stack.back() && JSON_HEDLEY_UNLIKELY(len != static_cast<std::size_t>(-1) && len > ref_stack.back()->max_size()))
6468 {
6469 JSON_THROW(out_of_range::create(408, concat("excessive array size: ", std::to_string(len)), ref_stack.back()));
6470 }
6471
6472 return true;
6473 }
6474
6476 {
6477 bool keep = true;
6478
6479 if (ref_stack.back())
6480 {
6481 keep = callback(static_cast<int>(ref_stack.size()) - 1, parse_event_t::array_end, *ref_stack.back());
6482 if (keep)
6483 {
6484 ref_stack.back()->set_parents();
6485 }
6486 else
6487 {
6488 // discard array
6489 *ref_stack.back() = discarded;
6490 }
6491 }
6492
6493 JSON_ASSERT(!ref_stack.empty());
6494 JSON_ASSERT(!keep_stack.empty());
6495 ref_stack.pop_back();
6496 keep_stack.pop_back();
6497
6498 // remove discarded value
6499 if (!keep && !ref_stack.empty() && ref_stack.back()->is_array())
6500 {
6501 ref_stack.back()->m_value.array->pop_back();
6502 }
6503
6504 return true;
6505 }
6506
6507 template<class Exception>
6508 bool parse_error(std::size_t /*unused*/, const std::string& /*unused*/,
6509 const Exception& ex)
6510 {
6511 errored = true;
6512 static_cast<void>(ex);
6513 if (allow_exceptions)
6514 {
6515 JSON_THROW(ex);
6516 }
6517 return false;
6518 }
6519
6520 constexpr bool is_errored() const
6521 {
6522 return errored;
6523 }
6524
6525 private:
6541 template<typename Value>
6542 std::pair<bool, BasicJsonType*> handle_value(Value&& v, const bool skip_callback = false)
6543 {
6544 JSON_ASSERT(!keep_stack.empty());
6545
6546 // do not handle this value if we know it would be added to a discarded
6547 // container
6548 if (!keep_stack.back())
6549 {
6550 return {false, nullptr};
6551 }
6552
6553 // create value
6554 auto value = BasicJsonType(std::forward<Value>(v));
6555
6556 // check callback
6557 const bool keep = skip_callback || callback(static_cast<int>(ref_stack.size()), parse_event_t::value, value);
6558
6559 // do not handle this value if we just learnt it shall be discarded
6560 if (!keep)
6561 {
6562 return {false, nullptr};
6563 }
6564
6565 if (ref_stack.empty())
6566 {
6567 root = std::move(value);
6568 return {true, &root};
6569 }
6570
6571 // skip this value if we already decided to skip the parent
6572 // (https://github.com/nlohmann/json/issues/971#issuecomment-413678360)
6573 if (!ref_stack.back())
6574 {
6575 return {false, nullptr};
6576 }
6577
6578 // we now only expect arrays and objects
6579 JSON_ASSERT(ref_stack.back()->is_array() || ref_stack.back()->is_object());
6580
6581 // array
6582 if (ref_stack.back()->is_array())
6583 {
6584 ref_stack.back()->m_value.array->emplace_back(std::move(value));
6585 return {true, &(ref_stack.back()->m_value.array->back())};
6586 }
6587
6588 // object
6589 JSON_ASSERT(ref_stack.back()->is_object());
6590 // check if we should store an element for the current key
6591 JSON_ASSERT(!key_keep_stack.empty());
6592 const bool store_element = key_keep_stack.back();
6593 key_keep_stack.pop_back();
6594
6595 if (!store_element)
6596 {
6597 return {false, nullptr};
6598 }
6599
6600 JSON_ASSERT(object_element);
6601 *object_element = std::move(value);
6602 return {true, object_element};
6603 }
6604
6606 BasicJsonType& root;
6608 std::vector<BasicJsonType*> ref_stack {};
6610 std::vector<bool> keep_stack {};
6612 std::vector<bool> key_keep_stack {};
6614 BasicJsonType* object_element = nullptr;
6616 bool errored = false;
6618 const parser_callback_t callback = nullptr;
6620 const bool allow_exceptions = true;
6622 BasicJsonType discarded = BasicJsonType::value_t::discarded;
6623};
6624
6625template<typename BasicJsonType>
6627{
6628 public:
6629 using number_integer_t = typename BasicJsonType::number_integer_t;
6630 using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
6631 using number_float_t = typename BasicJsonType::number_float_t;
6632 using string_t = typename BasicJsonType::string_t;
6633 using binary_t = typename BasicJsonType::binary_t;
6634
6635 bool null()
6636 {
6637 return true;
6638 }
6639
6640 bool boolean(bool /*unused*/)
6641 {
6642 return true;
6643 }
6644
6646 {
6647 return true;
6648 }
6649
6651 {
6652 return true;
6653 }
6654
6655 bool number_float(number_float_t /*unused*/, const string_t& /*unused*/)
6656 {
6657 return true;
6658 }
6659
6660 bool string(string_t& /*unused*/)
6661 {
6662 return true;
6663 }
6664
6665 bool binary(binary_t& /*unused*/)
6666 {
6667 return true;
6668 }
6669
6670 bool start_object(std::size_t /*unused*/ = static_cast<std::size_t>(-1))
6671 {
6672 return true;
6673 }
6674
6675 bool key(string_t& /*unused*/)
6676 {
6677 return true;
6678 }
6679
6681 {
6682 return true;
6683 }
6684
6685 bool start_array(std::size_t /*unused*/ = static_cast<std::size_t>(-1))
6686 {
6687 return true;
6688 }
6689
6691 {
6692 return true;
6693 }
6694
6695 bool parse_error(std::size_t /*unused*/, const std::string& /*unused*/, const detail::exception& /*unused*/)
6696 {
6697 return false;
6698 }
6699};
6700} // namespace detail
6701
6702} // namespace nlohmann
6703
6704// #include <nlohmann/detail/input/lexer.hpp>
6705
6706
6707#include <array> // array
6708#include <clocale> // localeconv
6709#include <cstddef> // size_t
6710#include <cstdio> // snprintf
6711#include <cstdlib> // strtof, strtod, strtold, strtoll, strtoull
6712#include <initializer_list> // initializer_list
6713#include <string> // char_traits, string
6714#include <utility> // move
6715#include <vector> // vector
6716
6717// #include <nlohmann/detail/input/input_adapters.hpp>
6718
6719// #include <nlohmann/detail/input/position_t.hpp>
6720
6721// #include <nlohmann/detail/macro_scope.hpp>
6722
6723
6724namespace nlohmann
6725{
6726namespace detail
6727{
6729// lexer //
6731
6732template<typename BasicJsonType>
6734{
6735 public:
6757
6761 static const char* token_type_name(const token_type t) noexcept
6762 {
6763 switch (t)
6764 {
6766 return "<uninitialized>";
6768 return "true literal";
6770 return "false literal";
6772 return "null literal";
6774 return "string literal";
6778 return "number literal";
6780 return "'['";
6782 return "'{'";
6784 return "']'";
6786 return "'}'";
6788 return "':'";
6790 return "','";
6792 return "<parse error>";
6794 return "end of input";
6796 return "'[', '{', or a literal";
6797 // LCOV_EXCL_START
6798 default: // catch non-enum values
6799 return "unknown token";
6800 // LCOV_EXCL_STOP
6801 }
6802 }
6803};
6809template<typename BasicJsonType, typename InputAdapterType>
6810class lexer : public lexer_base<BasicJsonType>
6811{
6812 using number_integer_t = typename BasicJsonType::number_integer_t;
6813 using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
6814 using number_float_t = typename BasicJsonType::number_float_t;
6815 using string_t = typename BasicJsonType::string_t;
6816 using char_type = typename InputAdapterType::char_type;
6817 using char_int_type = typename std::char_traits<char_type>::int_type;
6818
6819 public:
6821
6822 explicit lexer(InputAdapterType&& adapter, bool ignore_comments_ = false) noexcept
6823 : ia(std::move(adapter))
6824 , ignore_comments(ignore_comments_)
6825 , decimal_point_char(static_cast<char_int_type>(get_decimal_point()))
6826 {}
6827
6828 // delete because of pointer members
6829 lexer(const lexer&) = delete;
6830 lexer(lexer&&) = default; // NOLINT(hicpp-noexcept-move,performance-noexcept-move-constructor)
6831 lexer& operator=(lexer&) = delete;
6832 lexer& operator=(lexer&&) = default; // NOLINT(hicpp-noexcept-move,performance-noexcept-move-constructor)
6833 ~lexer() = default;
6834
6835 private:
6837 // locales
6839
6842 static char get_decimal_point() noexcept
6843 {
6844 const auto* loc = localeconv();
6845 JSON_ASSERT(loc != nullptr);
6846 return (loc->decimal_point == nullptr) ? '.' : *(loc->decimal_point);
6847 }
6848
6850 // scan functions
6852
6868 int get_codepoint()
6869 {
6870 // this function only makes sense after reading `\u`
6871 JSON_ASSERT(current == 'u');
6872 int codepoint = 0;
6873
6874 const auto factors = { 12u, 8u, 4u, 0u };
6875 for (const auto factor : factors)
6876 {
6877 get();
6878
6879 if (current >= '0' && current <= '9')
6880 {
6881 codepoint += static_cast<int>((static_cast<unsigned int>(current) - 0x30u) << factor);
6882 }
6883 else if (current >= 'A' && current <= 'F')
6884 {
6885 codepoint += static_cast<int>((static_cast<unsigned int>(current) - 0x37u) << factor);
6886 }
6887 else if (current >= 'a' && current <= 'f')
6888 {
6889 codepoint += static_cast<int>((static_cast<unsigned int>(current) - 0x57u) << factor);
6890 }
6891 else
6892 {
6893 return -1;
6894 }
6895 }
6896
6897 JSON_ASSERT(0x0000 <= codepoint && codepoint <= 0xFFFF);
6898 return codepoint;
6899 }
6900
6916 bool next_byte_in_range(std::initializer_list<char_int_type> ranges)
6917 {
6918 JSON_ASSERT(ranges.size() == 2 || ranges.size() == 4 || ranges.size() == 6);
6919 add(current);
6920
6921 for (auto range = ranges.begin(); range != ranges.end(); ++range)
6922 {
6923 get();
6924 if (JSON_HEDLEY_LIKELY(*range <= current && current <= *(++range)))
6925 {
6926 add(current);
6927 }
6928 else
6929 {
6930 error_message = "invalid string: ill-formed UTF-8 byte";
6931 return false;
6932 }
6933 }
6934
6935 return true;
6936 }
6937
6953 token_type scan_string()
6954 {
6955 // reset token_buffer (ignore opening quote)
6956 reset();
6957
6958 // we entered the function by reading an open quote
6959 JSON_ASSERT(current == '\"');
6960
6961 while (true)
6962 {
6963 // get next character
6964 switch (get())
6965 {
6966 // end of file while parsing string
6967 case std::char_traits<char_type>::eof():
6968 {
6969 error_message = "invalid string: missing closing quote";
6970 return token_type::parse_error;
6971 }
6972
6973 // closing quote
6974 case '\"':
6975 {
6976 return token_type::value_string;
6977 }
6978
6979 // escapes
6980 case '\\':
6981 {
6982 switch (get())
6983 {
6984 // quotation mark
6985 case '\"':
6986 add('\"');
6987 break;
6988 // reverse solidus
6989 case '\\':
6990 add('\\');
6991 break;
6992 // solidus
6993 case '/':
6994 add('/');
6995 break;
6996 // backspace
6997 case 'b':
6998 add('\b');
6999 break;
7000 // form feed
7001 case 'f':
7002 add('\f');
7003 break;
7004 // line feed
7005 case 'n':
7006 add('\n');
7007 break;
7008 // carriage return
7009 case 'r':
7010 add('\r');
7011 break;
7012 // tab
7013 case 't':
7014 add('\t');
7015 break;
7016
7017 // unicode escapes
7018 case 'u':
7019 {
7020 const int codepoint1 = get_codepoint();
7021 int codepoint = codepoint1; // start with codepoint1
7022
7023 if (JSON_HEDLEY_UNLIKELY(codepoint1 == -1))
7024 {
7025 error_message = "invalid string: '\\u' must be followed by 4 hex digits";
7026 return token_type::parse_error;
7027 }
7028
7029 // check if code point is a high surrogate
7030 if (0xD800 <= codepoint1 && codepoint1 <= 0xDBFF)
7031 {
7032 // expect next \uxxxx entry
7033 if (JSON_HEDLEY_LIKELY(get() == '\\' && get() == 'u'))
7034 {
7035 const int codepoint2 = get_codepoint();
7036
7037 if (JSON_HEDLEY_UNLIKELY(codepoint2 == -1))
7038 {
7039 error_message = "invalid string: '\\u' must be followed by 4 hex digits";
7040 return token_type::parse_error;
7041 }
7042
7043 // check if codepoint2 is a low surrogate
7044 if (JSON_HEDLEY_LIKELY(0xDC00 <= codepoint2 && codepoint2 <= 0xDFFF))
7045 {
7046 // overwrite codepoint
7047 codepoint = static_cast<int>(
7048 // high surrogate occupies the most significant 22 bits
7049 (static_cast<unsigned int>(codepoint1) << 10u)
7050 // low surrogate occupies the least significant 15 bits
7051 + static_cast<unsigned int>(codepoint2)
7052 // there is still the 0xD800, 0xDC00 and 0x10000 noise
7053 // in the result, so we have to subtract with:
7054 // (0xD800 << 10) + DC00 - 0x10000 = 0x35FDC00
7055 - 0x35FDC00u);
7056 }
7057 else
7058 {
7059 error_message = "invalid string: surrogate U+D800..U+DBFF must be followed by U+DC00..U+DFFF";
7060 return token_type::parse_error;
7061 }
7062 }
7063 else
7064 {
7065 error_message = "invalid string: surrogate U+D800..U+DBFF must be followed by U+DC00..U+DFFF";
7066 return token_type::parse_error;
7067 }
7068 }
7069 else
7070 {
7071 if (JSON_HEDLEY_UNLIKELY(0xDC00 <= codepoint1 && codepoint1 <= 0xDFFF))
7072 {
7073 error_message = "invalid string: surrogate U+DC00..U+DFFF must follow U+D800..U+DBFF";
7074 return token_type::parse_error;
7075 }
7076 }
7077
7078 // result of the above calculation yields a proper codepoint
7079 JSON_ASSERT(0x00 <= codepoint && codepoint <= 0x10FFFF);
7080
7081 // translate codepoint into bytes
7082 if (codepoint < 0x80)
7083 {
7084 // 1-byte characters: 0xxxxxxx (ASCII)
7085 add(static_cast<char_int_type>(codepoint));
7086 }
7087 else if (codepoint <= 0x7FF)
7088 {
7089 // 2-byte characters: 110xxxxx 10xxxxxx
7090 add(static_cast<char_int_type>(0xC0u | (static_cast<unsigned int>(codepoint) >> 6u)));
7091 add(static_cast<char_int_type>(0x80u | (static_cast<unsigned int>(codepoint) & 0x3Fu)));
7092 }
7093 else if (codepoint <= 0xFFFF)
7094 {
7095 // 3-byte characters: 1110xxxx 10xxxxxx 10xxxxxx
7096 add(static_cast<char_int_type>(0xE0u | (static_cast<unsigned int>(codepoint) >> 12u)));
7097 add(static_cast<char_int_type>(0x80u | ((static_cast<unsigned int>(codepoint) >> 6u) & 0x3Fu)));
7098 add(static_cast<char_int_type>(0x80u | (static_cast<unsigned int>(codepoint) & 0x3Fu)));
7099 }
7100 else
7101 {
7102 // 4-byte characters: 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
7103 add(static_cast<char_int_type>(0xF0u | (static_cast<unsigned int>(codepoint) >> 18u)));
7104 add(static_cast<char_int_type>(0x80u | ((static_cast<unsigned int>(codepoint) >> 12u) & 0x3Fu)));
7105 add(static_cast<char_int_type>(0x80u | ((static_cast<unsigned int>(codepoint) >> 6u) & 0x3Fu)));
7106 add(static_cast<char_int_type>(0x80u | (static_cast<unsigned int>(codepoint) & 0x3Fu)));
7107 }
7108
7109 break;
7110 }
7111
7112 // other characters after escape
7113 default:
7114 error_message = "invalid string: forbidden character after backslash";
7115 return token_type::parse_error;
7116 }
7117
7118 break;
7119 }
7120
7121 // invalid control characters
7122 case 0x00:
7123 {
7124 error_message = "invalid string: control character U+0000 (NUL) must be escaped to \\u0000";
7125 return token_type::parse_error;
7126 }
7127
7128 case 0x01:
7129 {
7130 error_message = "invalid string: control character U+0001 (SOH) must be escaped to \\u0001";
7131 return token_type::parse_error;
7132 }
7133
7134 case 0x02:
7135 {
7136 error_message = "invalid string: control character U+0002 (STX) must be escaped to \\u0002";
7137 return token_type::parse_error;
7138 }
7139
7140 case 0x03:
7141 {
7142 error_message = "invalid string: control character U+0003 (ETX) must be escaped to \\u0003";
7143 return token_type::parse_error;
7144 }
7145
7146 case 0x04:
7147 {
7148 error_message = "invalid string: control character U+0004 (EOT) must be escaped to \\u0004";
7149 return token_type::parse_error;
7150 }
7151
7152 case 0x05:
7153 {
7154 error_message = "invalid string: control character U+0005 (ENQ) must be escaped to \\u0005";
7155 return token_type::parse_error;
7156 }
7157
7158 case 0x06:
7159 {
7160 error_message = "invalid string: control character U+0006 (ACK) must be escaped to \\u0006";
7161 return token_type::parse_error;
7162 }
7163
7164 case 0x07:
7165 {
7166 error_message = "invalid string: control character U+0007 (BEL) must be escaped to \\u0007";
7167 return token_type::parse_error;
7168 }
7169
7170 case 0x08:
7171 {
7172 error_message = "invalid string: control character U+0008 (BS) must be escaped to \\u0008 or \\b";
7173 return token_type::parse_error;
7174 }
7175
7176 case 0x09:
7177 {
7178 error_message = "invalid string: control character U+0009 (HT) must be escaped to \\u0009 or \\t";
7179 return token_type::parse_error;
7180 }
7181
7182 case 0x0A:
7183 {
7184 error_message = "invalid string: control character U+000A (LF) must be escaped to \\u000A or \\n";
7185 return token_type::parse_error;
7186 }
7187
7188 case 0x0B:
7189 {
7190 error_message = "invalid string: control character U+000B (VT) must be escaped to \\u000B";
7191 return token_type::parse_error;
7192 }
7193
7194 case 0x0C:
7195 {
7196 error_message = "invalid string: control character U+000C (FF) must be escaped to \\u000C or \\f";
7197 return token_type::parse_error;
7198 }
7199
7200 case 0x0D:
7201 {
7202 error_message = "invalid string: control character U+000D (CR) must be escaped to \\u000D or \\r";
7203 return token_type::parse_error;
7204 }
7205
7206 case 0x0E:
7207 {
7208 error_message = "invalid string: control character U+000E (SO) must be escaped to \\u000E";
7209 return token_type::parse_error;
7210 }
7211
7212 case 0x0F:
7213 {
7214 error_message = "invalid string: control character U+000F (SI) must be escaped to \\u000F";
7215 return token_type::parse_error;
7216 }
7217
7218 case 0x10:
7219 {
7220 error_message = "invalid string: control character U+0010 (DLE) must be escaped to \\u0010";
7221 return token_type::parse_error;
7222 }
7223
7224 case 0x11:
7225 {
7226 error_message = "invalid string: control character U+0011 (DC1) must be escaped to \\u0011";
7227 return token_type::parse_error;
7228 }
7229
7230 case 0x12:
7231 {
7232 error_message = "invalid string: control character U+0012 (DC2) must be escaped to \\u0012";
7233 return token_type::parse_error;
7234 }
7235
7236 case 0x13:
7237 {
7238 error_message = "invalid string: control character U+0013 (DC3) must be escaped to \\u0013";
7239 return token_type::parse_error;
7240 }
7241
7242 case 0x14:
7243 {
7244 error_message = "invalid string: control character U+0014 (DC4) must be escaped to \\u0014";
7245 return token_type::parse_error;
7246 }
7247
7248 case 0x15:
7249 {
7250 error_message = "invalid string: control character U+0015 (NAK) must be escaped to \\u0015";
7251 return token_type::parse_error;
7252 }
7253
7254 case 0x16:
7255 {
7256 error_message = "invalid string: control character U+0016 (SYN) must be escaped to \\u0016";
7257 return token_type::parse_error;
7258 }
7259
7260 case 0x17:
7261 {
7262 error_message = "invalid string: control character U+0017 (ETB) must be escaped to \\u0017";
7263 return token_type::parse_error;
7264 }
7265
7266 case 0x18:
7267 {
7268 error_message = "invalid string: control character U+0018 (CAN) must be escaped to \\u0018";
7269 return token_type::parse_error;
7270 }
7271
7272 case 0x19:
7273 {
7274 error_message = "invalid string: control character U+0019 (EM) must be escaped to \\u0019";
7275 return token_type::parse_error;
7276 }
7277
7278 case 0x1A:
7279 {
7280 error_message = "invalid string: control character U+001A (SUB) must be escaped to \\u001A";
7281 return token_type::parse_error;
7282 }
7283
7284 case 0x1B:
7285 {
7286 error_message = "invalid string: control character U+001B (ESC) must be escaped to \\u001B";
7287 return token_type::parse_error;
7288 }
7289
7290 case 0x1C:
7291 {
7292 error_message = "invalid string: control character U+001C (FS) must be escaped to \\u001C";
7293 return token_type::parse_error;
7294 }
7295
7296 case 0x1D:
7297 {
7298 error_message = "invalid string: control character U+001D (GS) must be escaped to \\u001D";
7299 return token_type::parse_error;
7300 }
7301
7302 case 0x1E:
7303 {
7304 error_message = "invalid string: control character U+001E (RS) must be escaped to \\u001E";
7305 return token_type::parse_error;
7306 }
7307
7308 case 0x1F:
7309 {
7310 error_message = "invalid string: control character U+001F (US) must be escaped to \\u001F";
7311 return token_type::parse_error;
7312 }
7313
7314 // U+0020..U+007F (except U+0022 (quote) and U+005C (backspace))
7315 case 0x20:
7316 case 0x21:
7317 case 0x23:
7318 case 0x24:
7319 case 0x25:
7320 case 0x26:
7321 case 0x27:
7322 case 0x28:
7323 case 0x29:
7324 case 0x2A:
7325 case 0x2B:
7326 case 0x2C:
7327 case 0x2D:
7328 case 0x2E:
7329 case 0x2F:
7330 case 0x30:
7331 case 0x31:
7332 case 0x32:
7333 case 0x33:
7334 case 0x34:
7335 case 0x35:
7336 case 0x36:
7337 case 0x37:
7338 case 0x38:
7339 case 0x39:
7340 case 0x3A:
7341 case 0x3B:
7342 case 0x3C:
7343 case 0x3D:
7344 case 0x3E:
7345 case 0x3F:
7346 case 0x40:
7347 case 0x41:
7348 case 0x42:
7349 case 0x43:
7350 case 0x44:
7351 case 0x45:
7352 case 0x46:
7353 case 0x47:
7354 case 0x48:
7355 case 0x49:
7356 case 0x4A:
7357 case 0x4B:
7358 case 0x4C:
7359 case 0x4D:
7360 case 0x4E:
7361 case 0x4F:
7362 case 0x50:
7363 case 0x51:
7364 case 0x52:
7365 case 0x53:
7366 case 0x54:
7367 case 0x55:
7368 case 0x56:
7369 case 0x57:
7370 case 0x58:
7371 case 0x59:
7372 case 0x5A:
7373 case 0x5B:
7374 case 0x5D:
7375 case 0x5E:
7376 case 0x5F:
7377 case 0x60:
7378 case 0x61:
7379 case 0x62:
7380 case 0x63:
7381 case 0x64:
7382 case 0x65:
7383 case 0x66:
7384 case 0x67:
7385 case 0x68:
7386 case 0x69:
7387 case 0x6A:
7388 case 0x6B:
7389 case 0x6C:
7390 case 0x6D:
7391 case 0x6E:
7392 case 0x6F:
7393 case 0x70:
7394 case 0x71:
7395 case 0x72:
7396 case 0x73:
7397 case 0x74:
7398 case 0x75:
7399 case 0x76:
7400 case 0x77:
7401 case 0x78:
7402 case 0x79:
7403 case 0x7A:
7404 case 0x7B:
7405 case 0x7C:
7406 case 0x7D:
7407 case 0x7E:
7408 case 0x7F:
7409 {
7410 add(current);
7411 break;
7412 }
7413
7414 // U+0080..U+07FF: bytes C2..DF 80..BF
7415 case 0xC2:
7416 case 0xC3:
7417 case 0xC4:
7418 case 0xC5:
7419 case 0xC6:
7420 case 0xC7:
7421 case 0xC8:
7422 case 0xC9:
7423 case 0xCA:
7424 case 0xCB:
7425 case 0xCC:
7426 case 0xCD:
7427 case 0xCE:
7428 case 0xCF:
7429 case 0xD0:
7430 case 0xD1:
7431 case 0xD2:
7432 case 0xD3:
7433 case 0xD4:
7434 case 0xD5:
7435 case 0xD6:
7436 case 0xD7:
7437 case 0xD8:
7438 case 0xD9:
7439 case 0xDA:
7440 case 0xDB:
7441 case 0xDC:
7442 case 0xDD:
7443 case 0xDE:
7444 case 0xDF:
7445 {
7446 if (JSON_HEDLEY_UNLIKELY(!next_byte_in_range({0x80, 0xBF})))
7447 {
7448 return token_type::parse_error;
7449 }
7450 break;
7451 }
7452
7453 // U+0800..U+0FFF: bytes E0 A0..BF 80..BF
7454 case 0xE0:
7455 {
7456 if (JSON_HEDLEY_UNLIKELY(!(next_byte_in_range({0xA0, 0xBF, 0x80, 0xBF}))))
7457 {
7458 return token_type::parse_error;
7459 }
7460 break;
7461 }
7462
7463 // U+1000..U+CFFF: bytes E1..EC 80..BF 80..BF
7464 // U+E000..U+FFFF: bytes EE..EF 80..BF 80..BF
7465 case 0xE1:
7466 case 0xE2:
7467 case 0xE3:
7468 case 0xE4:
7469 case 0xE5:
7470 case 0xE6:
7471 case 0xE7:
7472 case 0xE8:
7473 case 0xE9:
7474 case 0xEA:
7475 case 0xEB:
7476 case 0xEC:
7477 case 0xEE:
7478 case 0xEF:
7479 {
7480 if (JSON_HEDLEY_UNLIKELY(!(next_byte_in_range({0x80, 0xBF, 0x80, 0xBF}))))
7481 {
7482 return token_type::parse_error;
7483 }
7484 break;
7485 }
7486
7487 // U+D000..U+D7FF: bytes ED 80..9F 80..BF
7488 case 0xED:
7489 {
7490 if (JSON_HEDLEY_UNLIKELY(!(next_byte_in_range({0x80, 0x9F, 0x80, 0xBF}))))
7491 {
7492 return token_type::parse_error;
7493 }
7494 break;
7495 }
7496
7497 // U+10000..U+3FFFF F0 90..BF 80..BF 80..BF
7498 case 0xF0:
7499 {
7500 if (JSON_HEDLEY_UNLIKELY(!(next_byte_in_range({0x90, 0xBF, 0x80, 0xBF, 0x80, 0xBF}))))
7501 {
7502 return token_type::parse_error;
7503 }
7504 break;
7505 }
7506
7507 // U+40000..U+FFFFF F1..F3 80..BF 80..BF 80..BF
7508 case 0xF1:
7509 case 0xF2:
7510 case 0xF3:
7511 {
7512 if (JSON_HEDLEY_UNLIKELY(!(next_byte_in_range({0x80, 0xBF, 0x80, 0xBF, 0x80, 0xBF}))))
7513 {
7514 return token_type::parse_error;
7515 }
7516 break;
7517 }
7518
7519 // U+100000..U+10FFFF F4 80..8F 80..BF 80..BF
7520 case 0xF4:
7521 {
7522 if (JSON_HEDLEY_UNLIKELY(!(next_byte_in_range({0x80, 0x8F, 0x80, 0xBF, 0x80, 0xBF}))))
7523 {
7524 return token_type::parse_error;
7525 }
7526 break;
7527 }
7528
7529 // remaining bytes (80..C1 and F5..FF) are ill-formed
7530 default:
7531 {
7532 error_message = "invalid string: ill-formed UTF-8 byte";
7533 return token_type::parse_error;
7534 }
7535 }
7536 }
7537 }
7538
7543 bool scan_comment()
7544 {
7545 switch (get())
7546 {
7547 // single-line comments skip input until a newline or EOF is read
7548 case '/':
7549 {
7550 while (true)
7551 {
7552 switch (get())
7553 {
7554 case '\n':
7555 case '\r':
7556 case std::char_traits<char_type>::eof():
7557 case '\0':
7558 return true;
7559
7560 default:
7561 break;
7562 }
7563 }
7564 }
7565
7566 // multi-line comments skip input until */ is read
7567 case '*':
7568 {
7569 while (true)
7570 {
7571 switch (get())
7572 {
7573 case std::char_traits<char_type>::eof():
7574 case '\0':
7575 {
7576 error_message = "invalid comment; missing closing '*/'";
7577 return false;
7578 }
7579
7580 case '*':
7581 {
7582 switch (get())
7583 {
7584 case '/':
7585 return true;
7586
7587 default:
7588 {
7589 unget();
7590 continue;
7591 }
7592 }
7593 }
7594
7595 default:
7596 continue;
7597 }
7598 }
7599 }
7600
7601 // unexpected character after reading '/'
7602 default:
7603 {
7604 error_message = "invalid comment; expecting '/' or '*' after '/'";
7605 return false;
7606 }
7607 }
7608 }
7609
7611 static void strtof(float& f, const char* str, char** endptr) noexcept
7612 {
7613 f = std::strtof(str, endptr);
7614 }
7615
7617 static void strtof(double& f, const char* str, char** endptr) noexcept
7618 {
7619 f = std::strtod(str, endptr);
7620 }
7621
7623 static void strtof(long double& f, const char* str, char** endptr) noexcept
7624 {
7625 f = std::strtold(str, endptr);
7626 }
7627
7668 token_type scan_number() // lgtm [cpp/use-of-goto]
7669 {
7670 // reset token_buffer to store the number's bytes
7671 reset();
7672
7673 // the type of the parsed number; initially set to unsigned; will be
7674 // changed if minus sign, decimal point or exponent is read
7675 token_type number_type = token_type::value_unsigned;
7676
7677 // state (init): we just found out we need to scan a number
7678 switch (current)
7679 {
7680 case '-':
7681 {
7682 add(current);
7683 goto scan_number_minus;
7684 }
7685
7686 case '0':
7687 {
7688 add(current);
7689 goto scan_number_zero;
7690 }
7691
7692 case '1':
7693 case '2':
7694 case '3':
7695 case '4':
7696 case '5':
7697 case '6':
7698 case '7':
7699 case '8':
7700 case '9':
7701 {
7702 add(current);
7703 goto scan_number_any1;
7704 }
7705
7706 // all other characters are rejected outside scan_number()
7707 default: // LCOV_EXCL_LINE
7708 JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert) LCOV_EXCL_LINE
7709 }
7710
7711scan_number_minus:
7712 // state: we just parsed a leading minus sign
7713 number_type = token_type::value_integer;
7714 switch (get())
7715 {
7716 case '0':
7717 {
7718 add(current);
7719 goto scan_number_zero;
7720 }
7721
7722 case '1':
7723 case '2':
7724 case '3':
7725 case '4':
7726 case '5':
7727 case '6':
7728 case '7':
7729 case '8':
7730 case '9':
7731 {
7732 add(current);
7733 goto scan_number_any1;
7734 }
7735
7736 default:
7737 {
7738 error_message = "invalid number; expected digit after '-'";
7739 return token_type::parse_error;
7740 }
7741 }
7742
7743scan_number_zero:
7744 // state: we just parse a zero (maybe with a leading minus sign)
7745 switch (get())
7746 {
7747 case '.':
7748 {
7749 add(decimal_point_char);
7750 goto scan_number_decimal1;
7751 }
7752
7753 case 'e':
7754 case 'E':
7755 {
7756 add(current);
7757 goto scan_number_exponent;
7758 }
7759
7760 default:
7761 goto scan_number_done;
7762 }
7763
7764scan_number_any1:
7765 // state: we just parsed a number 0-9 (maybe with a leading minus sign)
7766 switch (get())
7767 {
7768 case '0':
7769 case '1':
7770 case '2':
7771 case '3':
7772 case '4':
7773 case '5':
7774 case '6':
7775 case '7':
7776 case '8':
7777 case '9':
7778 {
7779 add(current);
7780 goto scan_number_any1;
7781 }
7782
7783 case '.':
7784 {
7785 add(decimal_point_char);
7786 goto scan_number_decimal1;
7787 }
7788
7789 case 'e':
7790 case 'E':
7791 {
7792 add(current);
7793 goto scan_number_exponent;
7794 }
7795
7796 default:
7797 goto scan_number_done;
7798 }
7799
7800scan_number_decimal1:
7801 // state: we just parsed a decimal point
7802 number_type = token_type::value_float;
7803 switch (get())
7804 {
7805 case '0':
7806 case '1':
7807 case '2':
7808 case '3':
7809 case '4':
7810 case '5':
7811 case '6':
7812 case '7':
7813 case '8':
7814 case '9':
7815 {
7816 add(current);
7817 goto scan_number_decimal2;
7818 }
7819
7820 default:
7821 {
7822 error_message = "invalid number; expected digit after '.'";
7823 return token_type::parse_error;
7824 }
7825 }
7826
7827scan_number_decimal2:
7828 // we just parsed at least one number after a decimal point
7829 switch (get())
7830 {
7831 case '0':
7832 case '1':
7833 case '2':
7834 case '3':
7835 case '4':
7836 case '5':
7837 case '6':
7838 case '7':
7839 case '8':
7840 case '9':
7841 {
7842 add(current);
7843 goto scan_number_decimal2;
7844 }
7845
7846 case 'e':
7847 case 'E':
7848 {
7849 add(current);
7850 goto scan_number_exponent;
7851 }
7852
7853 default:
7854 goto scan_number_done;
7855 }
7856
7857scan_number_exponent:
7858 // we just parsed an exponent
7859 number_type = token_type::value_float;
7860 switch (get())
7861 {
7862 case '+':
7863 case '-':
7864 {
7865 add(current);
7866 goto scan_number_sign;
7867 }
7868
7869 case '0':
7870 case '1':
7871 case '2':
7872 case '3':
7873 case '4':
7874 case '5':
7875 case '6':
7876 case '7':
7877 case '8':
7878 case '9':
7879 {
7880 add(current);
7881 goto scan_number_any2;
7882 }
7883
7884 default:
7885 {
7886 error_message =
7887 "invalid number; expected '+', '-', or digit after exponent";
7888 return token_type::parse_error;
7889 }
7890 }
7891
7892scan_number_sign:
7893 // we just parsed an exponent sign
7894 switch (get())
7895 {
7896 case '0':
7897 case '1':
7898 case '2':
7899 case '3':
7900 case '4':
7901 case '5':
7902 case '6':
7903 case '7':
7904 case '8':
7905 case '9':
7906 {
7907 add(current);
7908 goto scan_number_any2;
7909 }
7910
7911 default:
7912 {
7913 error_message = "invalid number; expected digit after exponent sign";
7914 return token_type::parse_error;
7915 }
7916 }
7917
7918scan_number_any2:
7919 // we just parsed a number after the exponent or exponent sign
7920 switch (get())
7921 {
7922 case '0':
7923 case '1':
7924 case '2':
7925 case '3':
7926 case '4':
7927 case '5':
7928 case '6':
7929 case '7':
7930 case '8':
7931 case '9':
7932 {
7933 add(current);
7934 goto scan_number_any2;
7935 }
7936
7937 default:
7938 goto scan_number_done;
7939 }
7940
7941scan_number_done:
7942 // unget the character after the number (we only read it to know that
7943 // we are done scanning a number)
7944 unget();
7945
7946 char* endptr = nullptr; // NOLINT(cppcoreguidelines-pro-type-vararg,hicpp-vararg)
7947 errno = 0;
7948
7949 // try to parse integers first and fall back to floats
7950 if (number_type == token_type::value_unsigned)
7951 {
7952 const auto x = std::strtoull(token_buffer.data(), &endptr, 10);
7953
7954 // we checked the number format before
7955 JSON_ASSERT(endptr == token_buffer.data() + token_buffer.size());
7956
7957 if (errno == 0)
7958 {
7959 value_unsigned = static_cast<number_unsigned_t>(x);
7960 if (value_unsigned == x)
7961 {
7962 return token_type::value_unsigned;
7963 }
7964 }
7965 }
7966 else if (number_type == token_type::value_integer)
7967 {
7968 const auto x = std::strtoll(token_buffer.data(), &endptr, 10);
7969
7970 // we checked the number format before
7971 JSON_ASSERT(endptr == token_buffer.data() + token_buffer.size());
7972
7973 if (errno == 0)
7974 {
7975 value_integer = static_cast<number_integer_t>(x);
7976 if (value_integer == x)
7977 {
7978 return token_type::value_integer;
7979 }
7980 }
7981 }
7982
7983 // this code is reached if we parse a floating-point number or if an
7984 // integer conversion above failed
7985 strtof(value_float, token_buffer.data(), &endptr);
7986
7987 // we checked the number format before
7988 JSON_ASSERT(endptr == token_buffer.data() + token_buffer.size());
7989
7990 return token_type::value_float;
7991 }
7992
7999 token_type scan_literal(const char_type* literal_text, const std::size_t length,
8000 token_type return_type)
8001 {
8002 JSON_ASSERT(std::char_traits<char_type>::to_char_type(current) == literal_text[0]);
8003 for (std::size_t i = 1; i < length; ++i)
8004 {
8005 if (JSON_HEDLEY_UNLIKELY(std::char_traits<char_type>::to_char_type(get()) != literal_text[i]))
8006 {
8007 error_message = "invalid literal";
8008 return token_type::parse_error;
8009 }
8010 }
8011 return return_type;
8012 }
8013
8015 // input management
8017
8019 void reset() noexcept
8020 {
8021 token_buffer.clear();
8022 token_string.clear();
8023 token_string.push_back(std::char_traits<char_type>::to_char_type(current));
8024 }
8025
8026 /*
8027 @brief get next character from the input
8028
8029 This function provides the interface to the used input adapter. It does
8030 not throw in case the input reached EOF, but returns a
8031 `std::char_traits<char>::eof()` in that case. Stores the scanned characters
8032 for use in error messages.
8033
8034 @return character read from the input
8035 */
8036 char_int_type get()
8037 {
8038 ++position.chars_read_total;
8039 ++position.chars_read_current_line;
8040
8041 if (next_unget)
8042 {
8043 // just reset the next_unget variable and work with current
8044 next_unget = false;
8045 }
8046 else
8047 {
8048 current = ia.get_character();
8049 }
8050
8051 if (JSON_HEDLEY_LIKELY(current != std::char_traits<char_type>::eof()))
8052 {
8053 token_string.push_back(std::char_traits<char_type>::to_char_type(current));
8054 }
8055
8056 if (current == '\n')
8057 {
8058 ++position.lines_read;
8059 position.chars_read_current_line = 0;
8060 }
8061
8062 return current;
8063 }
8064
8073 void unget()
8074 {
8075 next_unget = true;
8076
8077 --position.chars_read_total;
8078
8079 // in case we "unget" a newline, we have to also decrement the lines_read
8080 if (position.chars_read_current_line == 0)
8081 {
8082 if (position.lines_read > 0)
8083 {
8084 --position.lines_read;
8085 }
8086 }
8087 else
8088 {
8089 --position.chars_read_current_line;
8090 }
8091
8092 if (JSON_HEDLEY_LIKELY(current != std::char_traits<char_type>::eof()))
8093 {
8094 JSON_ASSERT(!token_string.empty());
8095 token_string.pop_back();
8096 }
8097 }
8098
8100 void add(char_int_type c)
8101 {
8102 token_buffer.push_back(static_cast<typename string_t::value_type>(c));
8103 }
8104
8105 public:
8107 // value getters
8109
8111 constexpr number_integer_t get_number_integer() const noexcept
8112 {
8113 return value_integer;
8114 }
8115
8117 constexpr number_unsigned_t get_number_unsigned() const noexcept
8118 {
8119 return value_unsigned;
8120 }
8121
8123 constexpr number_float_t get_number_float() const noexcept
8124 {
8125 return value_float;
8126 }
8127
8129 string_t& get_string()
8130 {
8131 return token_buffer;
8132 }
8133
8135 // diagnostics
8137
8139 constexpr position_t get_position() const noexcept
8140 {
8141 return position;
8142 }
8143
8147 std::string get_token_string() const
8148 {
8149 // escape control characters
8150 std::string result;
8151 for (const auto c : token_string)
8152 {
8153 if (static_cast<unsigned char>(c) <= '\x1F')
8154 {
8155 // escape control characters
8156 std::array<char, 9> cs{{}};
8157 static_cast<void>((std::snprintf)(cs.data(), cs.size(), "<U+%.4X>", static_cast<unsigned char>(c))); // NOLINT(cppcoreguidelines-pro-type-vararg,hicpp-vararg)
8158 result += cs.data();
8159 }
8160 else
8161 {
8162 // add character as is
8163 result.push_back(static_cast<std::string::value_type>(c));
8164 }
8165 }
8166
8167 return result;
8168 }
8169
8172 constexpr const char* get_error_message() const noexcept
8173 {
8174 return error_message;
8175 }
8176
8178 // actual scanner
8180
8186 {
8187 if (get() == 0xEF)
8188 {
8189 // check if we completely parse the BOM
8190 return get() == 0xBB && get() == 0xBF;
8191 }
8192
8193 // the first character is not the beginning of the BOM; unget it to
8194 // process is later
8195 unget();
8196 return true;
8197 }
8198
8200 {
8201 do
8202 {
8203 get();
8204 }
8205 while (current == ' ' || current == '\t' || current == '\n' || current == '\r');
8206 }
8207
8209 {
8210 // initially, skip the BOM
8211 if (position.chars_read_total == 0 && !skip_bom())
8212 {
8213 error_message = "invalid BOM; must be 0xEF 0xBB 0xBF if given";
8214 return token_type::parse_error;
8215 }
8216
8217 // read next character and ignore whitespace
8218 skip_whitespace();
8219
8220 // ignore comments
8221 while (ignore_comments && current == '/')
8222 {
8223 if (!scan_comment())
8224 {
8225 return token_type::parse_error;
8226 }
8227
8228 // skip following whitespace
8229 skip_whitespace();
8230 }
8231
8232 switch (current)
8233 {
8234 // structural characters
8235 case '[':
8236 return token_type::begin_array;
8237 case ']':
8238 return token_type::end_array;
8239 case '{':
8240 return token_type::begin_object;
8241 case '}':
8242 return token_type::end_object;
8243 case ':':
8244 return token_type::name_separator;
8245 case ',':
8246 return token_type::value_separator;
8247
8248 // literals
8249 case 't':
8250 {
8251 std::array<char_type, 4> true_literal = {{static_cast<char_type>('t'), static_cast<char_type>('r'), static_cast<char_type>('u'), static_cast<char_type>('e')}};
8252 return scan_literal(true_literal.data(), true_literal.size(), token_type::literal_true);
8253 }
8254 case 'f':
8255 {
8256 std::array<char_type, 5> false_literal = {{static_cast<char_type>('f'), static_cast<char_type>('a'), static_cast<char_type>('l'), static_cast<char_type>('s'), static_cast<char_type>('e')}};
8257 return scan_literal(false_literal.data(), false_literal.size(), token_type::literal_false);
8258 }
8259 case 'n':
8260 {
8261 std::array<char_type, 4> null_literal = {{static_cast<char_type>('n'), static_cast<char_type>('u'), static_cast<char_type>('l'), static_cast<char_type>('l')}};
8262 return scan_literal(null_literal.data(), null_literal.size(), token_type::literal_null);
8263 }
8264
8265 // string
8266 case '\"':
8267 return scan_string();
8268
8269 // number
8270 case '-':
8271 case '0':
8272 case '1':
8273 case '2':
8274 case '3':
8275 case '4':
8276 case '5':
8277 case '6':
8278 case '7':
8279 case '8':
8280 case '9':
8281 return scan_number();
8282
8283 // end of input (the null byte is needed when parsing from
8284 // string literals)
8285 case '\0':
8286 case std::char_traits<char_type>::eof():
8287 return token_type::end_of_input;
8288
8289 // error
8290 default:
8291 error_message = "invalid literal";
8292 return token_type::parse_error;
8293 }
8294 }
8295
8296 private:
8298 InputAdapterType ia;
8299
8301 const bool ignore_comments = false;
8302
8304 char_int_type current = std::char_traits<char_type>::eof();
8305
8307 bool next_unget = false;
8308
8311
8313 std::vector<char_type> token_string {};
8314
8316 string_t token_buffer {};
8317
8319 const char* error_message = "";
8320
8321 // number values
8322 number_integer_t value_integer = 0;
8323 number_unsigned_t value_unsigned = 0;
8324 number_float_t value_float = 0;
8325
8327 const char_int_type decimal_point_char = '.';
8328};
8329} // namespace detail
8330} // namespace nlohmann
8331
8332// #include <nlohmann/detail/macro_scope.hpp>
8333
8334// #include <nlohmann/detail/meta/is_sax.hpp>
8335
8336
8337#include <cstdint> // size_t
8338#include <utility> // declval
8339#include <string> // string
8340
8341// #include <nlohmann/detail/meta/detected.hpp>
8342
8343// #include <nlohmann/detail/meta/type_traits.hpp>
8344
8345
8346namespace nlohmann
8347{
8348namespace detail
8349{
8350template<typename T>
8351using null_function_t = decltype(std::declval<T&>().null());
8352
8353template<typename T>
8354using boolean_function_t =
8355 decltype(std::declval<T&>().boolean(std::declval<bool>()));
8356
8357template<typename T, typename Integer>
8358using number_integer_function_t =
8359 decltype(std::declval<T&>().number_integer(std::declval<Integer>()));
8360
8361template<typename T, typename Unsigned>
8362using number_unsigned_function_t =
8363 decltype(std::declval<T&>().number_unsigned(std::declval<Unsigned>()));
8364
8365template<typename T, typename Float, typename String>
8366using number_float_function_t = decltype(std::declval<T&>().number_float(
8367 std::declval<Float>(), std::declval<const String&>()));
8368
8369template<typename T, typename String>
8370using string_function_t =
8371 decltype(std::declval<T&>().string(std::declval<String&>()));
8372
8373template<typename T, typename Binary>
8374using binary_function_t =
8375 decltype(std::declval<T&>().binary(std::declval<Binary&>()));
8376
8377template<typename T>
8378using start_object_function_t =
8379 decltype(std::declval<T&>().start_object(std::declval<std::size_t>()));
8380
8381template<typename T, typename String>
8382using key_function_t =
8383 decltype(std::declval<T&>().key(std::declval<String&>()));
8384
8385template<typename T>
8386using end_object_function_t = decltype(std::declval<T&>().end_object());
8387
8388template<typename T>
8389using start_array_function_t =
8390 decltype(std::declval<T&>().start_array(std::declval<std::size_t>()));
8391
8392template<typename T>
8393using end_array_function_t = decltype(std::declval<T&>().end_array());
8394
8395template<typename T, typename Exception>
8396using parse_error_function_t = decltype(std::declval<T&>().parse_error(
8397 std::declval<std::size_t>(), std::declval<const std::string&>(),
8398 std::declval<const Exception&>()));
8399
8400template<typename SAX, typename BasicJsonType>
8401struct is_sax
8402{
8403 private:
8404 static_assert(is_basic_json<BasicJsonType>::value,
8405 "BasicJsonType must be of type basic_json<...>");
8406
8407 using number_integer_t = typename BasicJsonType::number_integer_t;
8408 using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
8409 using number_float_t = typename BasicJsonType::number_float_t;
8410 using string_t = typename BasicJsonType::string_t;
8411 using binary_t = typename BasicJsonType::binary_t;
8412 using exception_t = typename BasicJsonType::exception;
8413
8414 public:
8415 static constexpr bool value =
8416 is_detected_exact<bool, null_function_t, SAX>::value &&
8417 is_detected_exact<bool, boolean_function_t, SAX>::value &&
8418 is_detected_exact<bool, number_integer_function_t, SAX, number_integer_t>::value &&
8419 is_detected_exact<bool, number_unsigned_function_t, SAX, number_unsigned_t>::value &&
8420 is_detected_exact<bool, number_float_function_t, SAX, number_float_t, string_t>::value &&
8421 is_detected_exact<bool, string_function_t, SAX, string_t>::value &&
8422 is_detected_exact<bool, binary_function_t, SAX, binary_t>::value &&
8423 is_detected_exact<bool, start_object_function_t, SAX>::value &&
8424 is_detected_exact<bool, key_function_t, SAX, string_t>::value &&
8425 is_detected_exact<bool, end_object_function_t, SAX>::value &&
8426 is_detected_exact<bool, start_array_function_t, SAX>::value &&
8427 is_detected_exact<bool, end_array_function_t, SAX>::value &&
8428 is_detected_exact<bool, parse_error_function_t, SAX, exception_t>::value;
8429};
8430
8431template<typename SAX, typename BasicJsonType>
8432struct is_sax_static_asserts
8433{
8434 private:
8435 static_assert(is_basic_json<BasicJsonType>::value,
8436 "BasicJsonType must be of type basic_json<...>");
8437
8438 using number_integer_t = typename BasicJsonType::number_integer_t;
8439 using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
8440 using number_float_t = typename BasicJsonType::number_float_t;
8441 using string_t = typename BasicJsonType::string_t;
8442 using binary_t = typename BasicJsonType::binary_t;
8443 using exception_t = typename BasicJsonType::exception;
8444
8445 public:
8446 static_assert(is_detected_exact<bool, null_function_t, SAX>::value,
8447 "Missing/invalid function: bool null()");
8448 static_assert(is_detected_exact<bool, boolean_function_t, SAX>::value,
8449 "Missing/invalid function: bool boolean(bool)");
8450 static_assert(is_detected_exact<bool, boolean_function_t, SAX>::value,
8451 "Missing/invalid function: bool boolean(bool)");
8452 static_assert(
8453 is_detected_exact<bool, number_integer_function_t, SAX,
8454 number_integer_t>::value,
8455 "Missing/invalid function: bool number_integer(number_integer_t)");
8456 static_assert(
8457 is_detected_exact<bool, number_unsigned_function_t, SAX,
8458 number_unsigned_t>::value,
8459 "Missing/invalid function: bool number_unsigned(number_unsigned_t)");
8460 static_assert(is_detected_exact<bool, number_float_function_t, SAX,
8461 number_float_t, string_t>::value,
8462 "Missing/invalid function: bool number_float(number_float_t, const string_t&)");
8463 static_assert(
8464 is_detected_exact<bool, string_function_t, SAX, string_t>::value,
8465 "Missing/invalid function: bool string(string_t&)");
8466 static_assert(
8467 is_detected_exact<bool, binary_function_t, SAX, binary_t>::value,
8468 "Missing/invalid function: bool binary(binary_t&)");
8469 static_assert(is_detected_exact<bool, start_object_function_t, SAX>::value,
8470 "Missing/invalid function: bool start_object(std::size_t)");
8471 static_assert(is_detected_exact<bool, key_function_t, SAX, string_t>::value,
8472 "Missing/invalid function: bool key(string_t&)");
8473 static_assert(is_detected_exact<bool, end_object_function_t, SAX>::value,
8474 "Missing/invalid function: bool end_object()");
8475 static_assert(is_detected_exact<bool, start_array_function_t, SAX>::value,
8476 "Missing/invalid function: bool start_array(std::size_t)");
8477 static_assert(is_detected_exact<bool, end_array_function_t, SAX>::value,
8478 "Missing/invalid function: bool end_array()");
8479 static_assert(
8480 is_detected_exact<bool, parse_error_function_t, SAX, exception_t>::value,
8481 "Missing/invalid function: bool parse_error(std::size_t, const "
8482 "std::string&, const exception&)");
8483};
8484} // namespace detail
8485} // namespace nlohmann
8486
8487// #include <nlohmann/detail/meta/type_traits.hpp>
8488
8489// #include <nlohmann/detail/string_concat.hpp>
8490
8491// #include <nlohmann/detail/value_t.hpp>
8492
8493
8494namespace nlohmann
8495{
8496namespace detail
8497{
8498
8501{
8502 error,
8503 ignore,
8504 store
8505};
8506
8514static inline bool little_endianness(int num = 1) noexcept
8515{
8516 return *reinterpret_cast<char*>(&num) == 1;
8517}
8518
8519
8521// binary reader //
8523
8527template<typename BasicJsonType, typename InputAdapterType, typename SAX = json_sax_dom_parser<BasicJsonType>>
8529{
8530 using number_integer_t = typename BasicJsonType::number_integer_t;
8531 using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
8532 using number_float_t = typename BasicJsonType::number_float_t;
8533 using string_t = typename BasicJsonType::string_t;
8534 using binary_t = typename BasicJsonType::binary_t;
8535 using json_sax_t = SAX;
8536 using char_type = typename InputAdapterType::char_type;
8537 using char_int_type = typename std::char_traits<char_type>::int_type;
8538
8539 public:
8545 explicit binary_reader(InputAdapterType&& adapter, const input_format_t format = input_format_t::json) noexcept : ia(std::move(adapter)), input_format(format)
8546 {
8547 (void)detail::is_sax_static_asserts<SAX, BasicJsonType> {};
8548 }
8549
8550 // make class move-only
8552 binary_reader(binary_reader&&) = default; // NOLINT(hicpp-noexcept-move,performance-noexcept-move-constructor)
8554 binary_reader& operator=(binary_reader&&) = default; // NOLINT(hicpp-noexcept-move,performance-noexcept-move-constructor)
8555 ~binary_reader() = default;
8556
8566 bool sax_parse(const input_format_t format,
8567 json_sax_t* sax_,
8568 const bool strict = true,
8569 const cbor_tag_handler_t tag_handler = cbor_tag_handler_t::error)
8570 {
8571 sax = sax_;
8572 bool result = false;
8573
8574 switch (format)
8575 {
8576 case input_format_t::bson:
8577 result = parse_bson_internal();
8578 break;
8579
8580 case input_format_t::cbor:
8581 result = parse_cbor_internal(true, tag_handler);
8582 break;
8583
8584 case input_format_t::msgpack:
8585 result = parse_msgpack_internal();
8586 break;
8587
8588 case input_format_t::ubjson:
8589 case input_format_t::bjdata:
8590 result = parse_ubjson_internal();
8591 break;
8592
8593 case input_format_t::json: // LCOV_EXCL_LINE
8594 default: // LCOV_EXCL_LINE
8595 JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert) LCOV_EXCL_LINE
8596 }
8597
8598 // strict mode: next byte must be EOF
8599 if (result && strict)
8600 {
8601 if (input_format == input_format_t::ubjson || input_format == input_format_t::bjdata)
8602 {
8603 get_ignore_noop();
8604 }
8605 else
8606 {
8607 get();
8608 }
8609
8610 if (JSON_HEDLEY_UNLIKELY(current != std::char_traits<char_type>::eof()))
8611 {
8612 return sax->parse_error(chars_read, get_token_string(), parse_error::create(110, chars_read,
8613 exception_message(input_format, concat("expected end of input; last byte: 0x", get_token_string()), "value"), nullptr));
8614 }
8615 }
8616
8617 return result;
8618 }
8619
8620 private:
8622 // BSON //
8624
8629 bool parse_bson_internal()
8630 {
8631 std::int32_t document_size{};
8632 get_number<std::int32_t, true>(input_format_t::bson, document_size);
8633
8634 if (JSON_HEDLEY_UNLIKELY(!sax->start_object(static_cast<std::size_t>(-1))))
8635 {
8636 return false;
8637 }
8638
8639 if (JSON_HEDLEY_UNLIKELY(!parse_bson_element_list(/*is_array*/false)))
8640 {
8641 return false;
8642 }
8643
8644 return sax->end_object();
8645 }
8646
8654 bool get_bson_cstr(string_t& result)
8655 {
8656 auto out = std::back_inserter(result);
8657 while (true)
8658 {
8659 get();
8660 if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format_t::bson, "cstring")))
8661 {
8662 return false;
8663 }
8664 if (current == 0x00)
8665 {
8666 return true;
8667 }
8668 *out++ = static_cast<typename string_t::value_type>(current);
8669 }
8670 }
8671
8683 template<typename NumberType>
8684 bool get_bson_string(const NumberType len, string_t& result)
8685 {
8686 if (JSON_HEDLEY_UNLIKELY(len < 1))
8687 {
8688 auto last_token = get_token_string();
8689 return sax->parse_error(chars_read, last_token, parse_error::create(112, chars_read,
8690 exception_message(input_format_t::bson, concat("string length must be at least 1, is ", std::to_string(len)), "string"), nullptr));
8691 }
8692
8693 return get_string(input_format_t::bson, len - static_cast<NumberType>(1), result) && get() != std::char_traits<char_type>::eof();
8694 }
8695
8705 template<typename NumberType>
8706 bool get_bson_binary(const NumberType len, binary_t& result)
8707 {
8708 if (JSON_HEDLEY_UNLIKELY(len < 0))
8709 {
8710 auto last_token = get_token_string();
8711 return sax->parse_error(chars_read, last_token, parse_error::create(112, chars_read,
8712 exception_message(input_format_t::bson, concat("byte array length cannot be negative, is ", std::to_string(len)), "binary"), nullptr));
8713 }
8714
8715 // All BSON binary values have a subtype
8716 std::uint8_t subtype{};
8717 get_number<std::uint8_t>(input_format_t::bson, subtype);
8718 result.set_subtype(subtype);
8719
8720 return get_binary(input_format_t::bson, len, result);
8721 }
8722
8733 bool parse_bson_element_internal(const char_int_type element_type,
8734 const std::size_t element_type_parse_position)
8735 {
8736 switch (element_type)
8737 {
8738 case 0x01: // double
8739 {
8740 double number{};
8741 return get_number<double, true>(input_format_t::bson, number) && sax->number_float(static_cast<number_float_t>(number), "");
8742 }
8743
8744 case 0x02: // string
8745 {
8746 std::int32_t len{};
8747 string_t value;
8748 return get_number<std::int32_t, true>(input_format_t::bson, len) && get_bson_string(len, value) && sax->string(value);
8749 }
8750
8751 case 0x03: // object
8752 {
8753 return parse_bson_internal();
8754 }
8755
8756 case 0x04: // array
8757 {
8758 return parse_bson_array();
8759 }
8760
8761 case 0x05: // binary
8762 {
8763 std::int32_t len{};
8764 binary_t value;
8765 return get_number<std::int32_t, true>(input_format_t::bson, len) && get_bson_binary(len, value) && sax->binary(value);
8766 }
8767
8768 case 0x08: // boolean
8769 {
8770 return sax->boolean(get() != 0);
8771 }
8772
8773 case 0x0A: // null
8774 {
8775 return sax->null();
8776 }
8777
8778 case 0x10: // int32
8779 {
8780 std::int32_t value{};
8781 return get_number<std::int32_t, true>(input_format_t::bson, value) && sax->number_integer(value);
8782 }
8783
8784 case 0x12: // int64
8785 {
8786 std::int64_t value{};
8787 return get_number<std::int64_t, true>(input_format_t::bson, value) && sax->number_integer(value);
8788 }
8789
8790 default: // anything else not supported (yet)
8791 {
8792 std::array<char, 3> cr{{}};
8793 static_cast<void>((std::snprintf)(cr.data(), cr.size(), "%.2hhX", static_cast<unsigned char>(element_type))); // NOLINT(cppcoreguidelines-pro-type-vararg,hicpp-vararg)
8794 std::string cr_str{cr.data()};
8795 return sax->parse_error(element_type_parse_position, cr_str,
8796 parse_error::create(114, element_type_parse_position, concat("Unsupported BSON record type 0x", cr_str), nullptr));
8797 }
8798 }
8799 }
8800
8813 bool parse_bson_element_list(const bool is_array)
8814 {
8815 string_t key;
8816
8817 while (auto element_type = get())
8818 {
8819 if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format_t::bson, "element list")))
8820 {
8821 return false;
8822 }
8823
8824 const std::size_t element_type_parse_position = chars_read;
8825 if (JSON_HEDLEY_UNLIKELY(!get_bson_cstr(key)))
8826 {
8827 return false;
8828 }
8829
8830 if (!is_array && !sax->key(key))
8831 {
8832 return false;
8833 }
8834
8835 if (JSON_HEDLEY_UNLIKELY(!parse_bson_element_internal(element_type, element_type_parse_position)))
8836 {
8837 return false;
8838 }
8839
8840 // get_bson_cstr only appends
8841 key.clear();
8842 }
8843
8844 return true;
8845 }
8846
8851 bool parse_bson_array()
8852 {
8853 std::int32_t document_size{};
8854 get_number<std::int32_t, true>(input_format_t::bson, document_size);
8855
8856 if (JSON_HEDLEY_UNLIKELY(!sax->start_array(static_cast<std::size_t>(-1))))
8857 {
8858 return false;
8859 }
8860
8861 if (JSON_HEDLEY_UNLIKELY(!parse_bson_element_list(/*is_array*/true)))
8862 {
8863 return false;
8864 }
8865
8866 return sax->end_array();
8867 }
8868
8870 // CBOR //
8872
8881 bool parse_cbor_internal(const bool get_char,
8882 const cbor_tag_handler_t tag_handler)
8883 {
8884 switch (get_char ? get() : current)
8885 {
8886 // EOF
8887 case std::char_traits<char_type>::eof():
8888 return unexpect_eof(input_format_t::cbor, "value");
8889
8890 // Integer 0x00..0x17 (0..23)
8891 case 0x00:
8892 case 0x01:
8893 case 0x02:
8894 case 0x03:
8895 case 0x04:
8896 case 0x05:
8897 case 0x06:
8898 case 0x07:
8899 case 0x08:
8900 case 0x09:
8901 case 0x0A:
8902 case 0x0B:
8903 case 0x0C:
8904 case 0x0D:
8905 case 0x0E:
8906 case 0x0F:
8907 case 0x10:
8908 case 0x11:
8909 case 0x12:
8910 case 0x13:
8911 case 0x14:
8912 case 0x15:
8913 case 0x16:
8914 case 0x17:
8915 return sax->number_unsigned(static_cast<number_unsigned_t>(current));
8916
8917 case 0x18: // Unsigned integer (one-byte uint8_t follows)
8918 {
8919 std::uint8_t number{};
8920 return get_number(input_format_t::cbor, number) && sax->number_unsigned(number);
8921 }
8922
8923 case 0x19: // Unsigned integer (two-byte uint16_t follows)
8924 {
8925 std::uint16_t number{};
8926 return get_number(input_format_t::cbor, number) && sax->number_unsigned(number);
8927 }
8928
8929 case 0x1A: // Unsigned integer (four-byte uint32_t follows)
8930 {
8931 std::uint32_t number{};
8932 return get_number(input_format_t::cbor, number) && sax->number_unsigned(number);
8933 }
8934
8935 case 0x1B: // Unsigned integer (eight-byte uint64_t follows)
8936 {
8937 std::uint64_t number{};
8938 return get_number(input_format_t::cbor, number) && sax->number_unsigned(number);
8939 }
8940
8941 // Negative integer -1-0x00..-1-0x17 (-1..-24)
8942 case 0x20:
8943 case 0x21:
8944 case 0x22:
8945 case 0x23:
8946 case 0x24:
8947 case 0x25:
8948 case 0x26:
8949 case 0x27:
8950 case 0x28:
8951 case 0x29:
8952 case 0x2A:
8953 case 0x2B:
8954 case 0x2C:
8955 case 0x2D:
8956 case 0x2E:
8957 case 0x2F:
8958 case 0x30:
8959 case 0x31:
8960 case 0x32:
8961 case 0x33:
8962 case 0x34:
8963 case 0x35:
8964 case 0x36:
8965 case 0x37:
8966 return sax->number_integer(static_cast<std::int8_t>(0x20 - 1 - current));
8967
8968 case 0x38: // Negative integer (one-byte uint8_t follows)
8969 {
8970 std::uint8_t number{};
8971 return get_number(input_format_t::cbor, number) && sax->number_integer(static_cast<number_integer_t>(-1) - number);
8972 }
8973
8974 case 0x39: // Negative integer -1-n (two-byte uint16_t follows)
8975 {
8976 std::uint16_t number{};
8977 return get_number(input_format_t::cbor, number) && sax->number_integer(static_cast<number_integer_t>(-1) - number);
8978 }
8979
8980 case 0x3A: // Negative integer -1-n (four-byte uint32_t follows)
8981 {
8982 std::uint32_t number{};
8983 return get_number(input_format_t::cbor, number) && sax->number_integer(static_cast<number_integer_t>(-1) - number);
8984 }
8985
8986 case 0x3B: // Negative integer -1-n (eight-byte uint64_t follows)
8987 {
8988 std::uint64_t number{};
8989 return get_number(input_format_t::cbor, number) && sax->number_integer(static_cast<number_integer_t>(-1)
8990 - static_cast<number_integer_t>(number));
8991 }
8992
8993 // Binary data (0x00..0x17 bytes follow)
8994 case 0x40:
8995 case 0x41:
8996 case 0x42:
8997 case 0x43:
8998 case 0x44:
8999 case 0x45:
9000 case 0x46:
9001 case 0x47:
9002 case 0x48:
9003 case 0x49:
9004 case 0x4A:
9005 case 0x4B:
9006 case 0x4C:
9007 case 0x4D:
9008 case 0x4E:
9009 case 0x4F:
9010 case 0x50:
9011 case 0x51:
9012 case 0x52:
9013 case 0x53:
9014 case 0x54:
9015 case 0x55:
9016 case 0x56:
9017 case 0x57:
9018 case 0x58: // Binary data (one-byte uint8_t for n follows)
9019 case 0x59: // Binary data (two-byte uint16_t for n follow)
9020 case 0x5A: // Binary data (four-byte uint32_t for n follow)
9021 case 0x5B: // Binary data (eight-byte uint64_t for n follow)
9022 case 0x5F: // Binary data (indefinite length)
9023 {
9024 binary_t b;
9025 return get_cbor_binary(b) && sax->binary(b);
9026 }
9027
9028 // UTF-8 string (0x00..0x17 bytes follow)
9029 case 0x60:
9030 case 0x61:
9031 case 0x62:
9032 case 0x63:
9033 case 0x64:
9034 case 0x65:
9035 case 0x66:
9036 case 0x67:
9037 case 0x68:
9038 case 0x69:
9039 case 0x6A:
9040 case 0x6B:
9041 case 0x6C:
9042 case 0x6D:
9043 case 0x6E:
9044 case 0x6F:
9045 case 0x70:
9046 case 0x71:
9047 case 0x72:
9048 case 0x73:
9049 case 0x74:
9050 case 0x75:
9051 case 0x76:
9052 case 0x77:
9053 case 0x78: // UTF-8 string (one-byte uint8_t for n follows)
9054 case 0x79: // UTF-8 string (two-byte uint16_t for n follow)
9055 case 0x7A: // UTF-8 string (four-byte uint32_t for n follow)
9056 case 0x7B: // UTF-8 string (eight-byte uint64_t for n follow)
9057 case 0x7F: // UTF-8 string (indefinite length)
9058 {
9059 string_t s;
9060 return get_cbor_string(s) && sax->string(s);
9061 }
9062
9063 // array (0x00..0x17 data items follow)
9064 case 0x80:
9065 case 0x81:
9066 case 0x82:
9067 case 0x83:
9068 case 0x84:
9069 case 0x85:
9070 case 0x86:
9071 case 0x87:
9072 case 0x88:
9073 case 0x89:
9074 case 0x8A:
9075 case 0x8B:
9076 case 0x8C:
9077 case 0x8D:
9078 case 0x8E:
9079 case 0x8F:
9080 case 0x90:
9081 case 0x91:
9082 case 0x92:
9083 case 0x93:
9084 case 0x94:
9085 case 0x95:
9086 case 0x96:
9087 case 0x97:
9088 return get_cbor_array(static_cast<std::size_t>(static_cast<unsigned int>(current) & 0x1Fu), tag_handler);
9089
9090 case 0x98: // array (one-byte uint8_t for n follows)
9091 {
9092 std::uint8_t len{};
9093 return get_number(input_format_t::cbor, len) && get_cbor_array(static_cast<std::size_t>(len), tag_handler);
9094 }
9095
9096 case 0x99: // array (two-byte uint16_t for n follow)
9097 {
9098 std::uint16_t len{};
9099 return get_number(input_format_t::cbor, len) && get_cbor_array(static_cast<std::size_t>(len), tag_handler);
9100 }
9101
9102 case 0x9A: // array (four-byte uint32_t for n follow)
9103 {
9104 std::uint32_t len{};
9105 return get_number(input_format_t::cbor, len) && get_cbor_array(static_cast<std::size_t>(len), tag_handler);
9106 }
9107
9108 case 0x9B: // array (eight-byte uint64_t for n follow)
9109 {
9110 std::uint64_t len{};
9111 return get_number(input_format_t::cbor, len) && get_cbor_array(detail::conditional_static_cast<std::size_t>(len), tag_handler);
9112 }
9113
9114 case 0x9F: // array (indefinite length)
9115 return get_cbor_array(static_cast<std::size_t>(-1), tag_handler);
9116
9117 // map (0x00..0x17 pairs of data items follow)
9118 case 0xA0:
9119 case 0xA1:
9120 case 0xA2:
9121 case 0xA3:
9122 case 0xA4:
9123 case 0xA5:
9124 case 0xA6:
9125 case 0xA7:
9126 case 0xA8:
9127 case 0xA9:
9128 case 0xAA:
9129 case 0xAB:
9130 case 0xAC:
9131 case 0xAD:
9132 case 0xAE:
9133 case 0xAF:
9134 case 0xB0:
9135 case 0xB1:
9136 case 0xB2:
9137 case 0xB3:
9138 case 0xB4:
9139 case 0xB5:
9140 case 0xB6:
9141 case 0xB7:
9142 return get_cbor_object(static_cast<std::size_t>(static_cast<unsigned int>(current) & 0x1Fu), tag_handler);
9143
9144 case 0xB8: // map (one-byte uint8_t for n follows)
9145 {
9146 std::uint8_t len{};
9147 return get_number(input_format_t::cbor, len) && get_cbor_object(static_cast<std::size_t>(len), tag_handler);
9148 }
9149
9150 case 0xB9: // map (two-byte uint16_t for n follow)
9151 {
9152 std::uint16_t len{};
9153 return get_number(input_format_t::cbor, len) && get_cbor_object(static_cast<std::size_t>(len), tag_handler);
9154 }
9155
9156 case 0xBA: // map (four-byte uint32_t for n follow)
9157 {
9158 std::uint32_t len{};
9159 return get_number(input_format_t::cbor, len) && get_cbor_object(static_cast<std::size_t>(len), tag_handler);
9160 }
9161
9162 case 0xBB: // map (eight-byte uint64_t for n follow)
9163 {
9164 std::uint64_t len{};
9165 return get_number(input_format_t::cbor, len) && get_cbor_object(detail::conditional_static_cast<std::size_t>(len), tag_handler);
9166 }
9167
9168 case 0xBF: // map (indefinite length)
9169 return get_cbor_object(static_cast<std::size_t>(-1), tag_handler);
9170
9171 case 0xC6: // tagged item
9172 case 0xC7:
9173 case 0xC8:
9174 case 0xC9:
9175 case 0xCA:
9176 case 0xCB:
9177 case 0xCC:
9178 case 0xCD:
9179 case 0xCE:
9180 case 0xCF:
9181 case 0xD0:
9182 case 0xD1:
9183 case 0xD2:
9184 case 0xD3:
9185 case 0xD4:
9186 case 0xD8: // tagged item (1 bytes follow)
9187 case 0xD9: // tagged item (2 bytes follow)
9188 case 0xDA: // tagged item (4 bytes follow)
9189 case 0xDB: // tagged item (8 bytes follow)
9190 {
9191 switch (tag_handler)
9192 {
9194 {
9195 auto last_token = get_token_string();
9196 return sax->parse_error(chars_read, last_token, parse_error::create(112, chars_read,
9197 exception_message(input_format_t::cbor, concat("invalid byte: 0x", last_token), "value"), nullptr));
9198 }
9199
9201 {
9202 // ignore binary subtype
9203 switch (current)
9204 {
9205 case 0xD8:
9206 {
9207 std::uint8_t subtype_to_ignore{};
9208 get_number(input_format_t::cbor, subtype_to_ignore);
9209 break;
9210 }
9211 case 0xD9:
9212 {
9213 std::uint16_t subtype_to_ignore{};
9214 get_number(input_format_t::cbor, subtype_to_ignore);
9215 break;
9216 }
9217 case 0xDA:
9218 {
9219 std::uint32_t subtype_to_ignore{};
9220 get_number(input_format_t::cbor, subtype_to_ignore);
9221 break;
9222 }
9223 case 0xDB:
9224 {
9225 std::uint64_t subtype_to_ignore{};
9226 get_number(input_format_t::cbor, subtype_to_ignore);
9227 break;
9228 }
9229 default:
9230 break;
9231 }
9232 return parse_cbor_internal(true, tag_handler);
9233 }
9234
9236 {
9237 binary_t b;
9238 // use binary subtype and store in binary container
9239 switch (current)
9240 {
9241 case 0xD8:
9242 {
9243 std::uint8_t subtype{};
9244 get_number(input_format_t::cbor, subtype);
9245 b.set_subtype(detail::conditional_static_cast<typename binary_t::subtype_type>(subtype));
9246 break;
9247 }
9248 case 0xD9:
9249 {
9250 std::uint16_t subtype{};
9251 get_number(input_format_t::cbor, subtype);
9252 b.set_subtype(detail::conditional_static_cast<typename binary_t::subtype_type>(subtype));
9253 break;
9254 }
9255 case 0xDA:
9256 {
9257 std::uint32_t subtype{};
9258 get_number(input_format_t::cbor, subtype);
9259 b.set_subtype(detail::conditional_static_cast<typename binary_t::subtype_type>(subtype));
9260 break;
9261 }
9262 case 0xDB:
9263 {
9264 std::uint64_t subtype{};
9265 get_number(input_format_t::cbor, subtype);
9266 b.set_subtype(detail::conditional_static_cast<typename binary_t::subtype_type>(subtype));
9267 break;
9268 }
9269 default:
9270 return parse_cbor_internal(true, tag_handler);
9271 }
9272 get();
9273 return get_cbor_binary(b) && sax->binary(b);
9274 }
9275
9276 default: // LCOV_EXCL_LINE
9277 JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert) LCOV_EXCL_LINE
9278 return false; // LCOV_EXCL_LINE
9279 }
9280 }
9281
9282 case 0xF4: // false
9283 return sax->boolean(false);
9284
9285 case 0xF5: // true
9286 return sax->boolean(true);
9287
9288 case 0xF6: // null
9289 return sax->null();
9290
9291 case 0xF9: // Half-Precision Float (two-byte IEEE 754)
9292 {
9293 const auto byte1_raw = get();
9294 if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format_t::cbor, "number")))
9295 {
9296 return false;
9297 }
9298 const auto byte2_raw = get();
9299 if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format_t::cbor, "number")))
9300 {
9301 return false;
9302 }
9303
9304 const auto byte1 = static_cast<unsigned char>(byte1_raw);
9305 const auto byte2 = static_cast<unsigned char>(byte2_raw);
9306
9307 // code from RFC 7049, Appendix D, Figure 3:
9308 // As half-precision floating-point numbers were only added
9309 // to IEEE 754 in 2008, today's programming platforms often
9310 // still only have limited support for them. It is very
9311 // easy to include at least decoding support for them even
9312 // without such support. An example of a small decoder for
9313 // half-precision floating-point numbers in the C language
9314 // is shown in Fig. 3.
9315 const auto half = static_cast<unsigned int>((byte1 << 8u) + byte2);
9316 const double val = [&half]
9317 {
9318 const int exp = (half >> 10u) & 0x1Fu;
9319 const unsigned int mant = half & 0x3FFu;
9320 JSON_ASSERT(0 <= exp&& exp <= 32);
9321 JSON_ASSERT(mant <= 1024);
9322 switch (exp)
9323 {
9324 case 0:
9325 return std::ldexp(mant, -24);
9326 case 31:
9327 return (mant == 0)
9328 ? std::numeric_limits<double>::infinity()
9329 : std::numeric_limits<double>::quiet_NaN();
9330 default:
9331 return std::ldexp(mant + 1024, exp - 25);
9332 }
9333 }();
9334 return sax->number_float((half & 0x8000u) != 0
9335 ? static_cast<number_float_t>(-val)
9336 : static_cast<number_float_t>(val), "");
9337 }
9338
9339 case 0xFA: // Single-Precision Float (four-byte IEEE 754)
9340 {
9341 float number{};
9342 return get_number(input_format_t::cbor, number) && sax->number_float(static_cast<number_float_t>(number), "");
9343 }
9344
9345 case 0xFB: // Double-Precision Float (eight-byte IEEE 754)
9346 {
9347 double number{};
9348 return get_number(input_format_t::cbor, number) && sax->number_float(static_cast<number_float_t>(number), "");
9349 }
9350
9351 default: // anything else (0xFF is handled inside the other types)
9352 {
9353 auto last_token = get_token_string();
9354 return sax->parse_error(chars_read, last_token, parse_error::create(112, chars_read,
9355 exception_message(input_format_t::cbor, concat("invalid byte: 0x", last_token), "value"), nullptr));
9356 }
9357 }
9358 }
9359
9371 bool get_cbor_string(string_t& result)
9372 {
9373 if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format_t::cbor, "string")))
9374 {
9375 return false;
9376 }
9377
9378 switch (current)
9379 {
9380 // UTF-8 string (0x00..0x17 bytes follow)
9381 case 0x60:
9382 case 0x61:
9383 case 0x62:
9384 case 0x63:
9385 case 0x64:
9386 case 0x65:
9387 case 0x66:
9388 case 0x67:
9389 case 0x68:
9390 case 0x69:
9391 case 0x6A:
9392 case 0x6B:
9393 case 0x6C:
9394 case 0x6D:
9395 case 0x6E:
9396 case 0x6F:
9397 case 0x70:
9398 case 0x71:
9399 case 0x72:
9400 case 0x73:
9401 case 0x74:
9402 case 0x75:
9403 case 0x76:
9404 case 0x77:
9405 {
9406 return get_string(input_format_t::cbor, static_cast<unsigned int>(current) & 0x1Fu, result);
9407 }
9408
9409 case 0x78: // UTF-8 string (one-byte uint8_t for n follows)
9410 {
9411 std::uint8_t len{};
9412 return get_number(input_format_t::cbor, len) && get_string(input_format_t::cbor, len, result);
9413 }
9414
9415 case 0x79: // UTF-8 string (two-byte uint16_t for n follow)
9416 {
9417 std::uint16_t len{};
9418 return get_number(input_format_t::cbor, len) && get_string(input_format_t::cbor, len, result);
9419 }
9420
9421 case 0x7A: // UTF-8 string (four-byte uint32_t for n follow)
9422 {
9423 std::uint32_t len{};
9424 return get_number(input_format_t::cbor, len) && get_string(input_format_t::cbor, len, result);
9425 }
9426
9427 case 0x7B: // UTF-8 string (eight-byte uint64_t for n follow)
9428 {
9429 std::uint64_t len{};
9430 return get_number(input_format_t::cbor, len) && get_string(input_format_t::cbor, len, result);
9431 }
9432
9433 case 0x7F: // UTF-8 string (indefinite length)
9434 {
9435 while (get() != 0xFF)
9436 {
9437 string_t chunk;
9438 if (!get_cbor_string(chunk))
9439 {
9440 return false;
9441 }
9442 result.append(chunk);
9443 }
9444 return true;
9445 }
9446
9447 default:
9448 {
9449 auto last_token = get_token_string();
9450 return sax->parse_error(chars_read, last_token, parse_error::create(113, chars_read,
9451 exception_message(input_format_t::cbor, concat("expected length specification (0x60-0x7B) or indefinite string type (0x7F); last byte: 0x", last_token), "string"), nullptr));
9452 }
9453 }
9454 }
9455
9467 bool get_cbor_binary(binary_t& result)
9468 {
9469 if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format_t::cbor, "binary")))
9470 {
9471 return false;
9472 }
9473
9474 switch (current)
9475 {
9476 // Binary data (0x00..0x17 bytes follow)
9477 case 0x40:
9478 case 0x41:
9479 case 0x42:
9480 case 0x43:
9481 case 0x44:
9482 case 0x45:
9483 case 0x46:
9484 case 0x47:
9485 case 0x48:
9486 case 0x49:
9487 case 0x4A:
9488 case 0x4B:
9489 case 0x4C:
9490 case 0x4D:
9491 case 0x4E:
9492 case 0x4F:
9493 case 0x50:
9494 case 0x51:
9495 case 0x52:
9496 case 0x53:
9497 case 0x54:
9498 case 0x55:
9499 case 0x56:
9500 case 0x57:
9501 {
9502 return get_binary(input_format_t::cbor, static_cast<unsigned int>(current) & 0x1Fu, result);
9503 }
9504
9505 case 0x58: // Binary data (one-byte uint8_t for n follows)
9506 {
9507 std::uint8_t len{};
9508 return get_number(input_format_t::cbor, len) &&
9509 get_binary(input_format_t::cbor, len, result);
9510 }
9511
9512 case 0x59: // Binary data (two-byte uint16_t for n follow)
9513 {
9514 std::uint16_t len{};
9515 return get_number(input_format_t::cbor, len) &&
9516 get_binary(input_format_t::cbor, len, result);
9517 }
9518
9519 case 0x5A: // Binary data (four-byte uint32_t for n follow)
9520 {
9521 std::uint32_t len{};
9522 return get_number(input_format_t::cbor, len) &&
9523 get_binary(input_format_t::cbor, len, result);
9524 }
9525
9526 case 0x5B: // Binary data (eight-byte uint64_t for n follow)
9527 {
9528 std::uint64_t len{};
9529 return get_number(input_format_t::cbor, len) &&
9530 get_binary(input_format_t::cbor, len, result);
9531 }
9532
9533 case 0x5F: // Binary data (indefinite length)
9534 {
9535 while (get() != 0xFF)
9536 {
9537 binary_t chunk;
9538 if (!get_cbor_binary(chunk))
9539 {
9540 return false;
9541 }
9542 result.insert(result.end(), chunk.begin(), chunk.end());
9543 }
9544 return true;
9545 }
9546
9547 default:
9548 {
9549 auto last_token = get_token_string();
9550 return sax->parse_error(chars_read, last_token, parse_error::create(113, chars_read,
9551 exception_message(input_format_t::cbor, concat("expected length specification (0x40-0x5B) or indefinite binary array type (0x5F); last byte: 0x", last_token), "binary"), nullptr));
9552 }
9553 }
9554 }
9555
9562 bool get_cbor_array(const std::size_t len,
9563 const cbor_tag_handler_t tag_handler)
9564 {
9565 if (JSON_HEDLEY_UNLIKELY(!sax->start_array(len)))
9566 {
9567 return false;
9568 }
9569
9570 if (len != static_cast<std::size_t>(-1))
9571 {
9572 for (std::size_t i = 0; i < len; ++i)
9573 {
9574 if (JSON_HEDLEY_UNLIKELY(!parse_cbor_internal(true, tag_handler)))
9575 {
9576 return false;
9577 }
9578 }
9579 }
9580 else
9581 {
9582 while (get() != 0xFF)
9583 {
9584 if (JSON_HEDLEY_UNLIKELY(!parse_cbor_internal(false, tag_handler)))
9585 {
9586 return false;
9587 }
9588 }
9589 }
9590
9591 return sax->end_array();
9592 }
9593
9600 bool get_cbor_object(const std::size_t len,
9601 const cbor_tag_handler_t tag_handler)
9602 {
9603 if (JSON_HEDLEY_UNLIKELY(!sax->start_object(len)))
9604 {
9605 return false;
9606 }
9607
9608 if (len != 0)
9609 {
9610 string_t key;
9611 if (len != static_cast<std::size_t>(-1))
9612 {
9613 for (std::size_t i = 0; i < len; ++i)
9614 {
9615 get();
9616 if (JSON_HEDLEY_UNLIKELY(!get_cbor_string(key) || !sax->key(key)))
9617 {
9618 return false;
9619 }
9620
9621 if (JSON_HEDLEY_UNLIKELY(!parse_cbor_internal(true, tag_handler)))
9622 {
9623 return false;
9624 }
9625 key.clear();
9626 }
9627 }
9628 else
9629 {
9630 while (get() != 0xFF)
9631 {
9632 if (JSON_HEDLEY_UNLIKELY(!get_cbor_string(key) || !sax->key(key)))
9633 {
9634 return false;
9635 }
9636
9637 if (JSON_HEDLEY_UNLIKELY(!parse_cbor_internal(true, tag_handler)))
9638 {
9639 return false;
9640 }
9641 key.clear();
9642 }
9643 }
9644 }
9645
9646 return sax->end_object();
9647 }
9648
9650 // MsgPack //
9652
9656 bool parse_msgpack_internal()
9657 {
9658 switch (get())
9659 {
9660 // EOF
9661 case std::char_traits<char_type>::eof():
9662 return unexpect_eof(input_format_t::msgpack, "value");
9663
9664 // positive fixint
9665 case 0x00:
9666 case 0x01:
9667 case 0x02:
9668 case 0x03:
9669 case 0x04:
9670 case 0x05:
9671 case 0x06:
9672 case 0x07:
9673 case 0x08:
9674 case 0x09:
9675 case 0x0A:
9676 case 0x0B:
9677 case 0x0C:
9678 case 0x0D:
9679 case 0x0E:
9680 case 0x0F:
9681 case 0x10:
9682 case 0x11:
9683 case 0x12:
9684 case 0x13:
9685 case 0x14:
9686 case 0x15:
9687 case 0x16:
9688 case 0x17:
9689 case 0x18:
9690 case 0x19:
9691 case 0x1A:
9692 case 0x1B:
9693 case 0x1C:
9694 case 0x1D:
9695 case 0x1E:
9696 case 0x1F:
9697 case 0x20:
9698 case 0x21:
9699 case 0x22:
9700 case 0x23:
9701 case 0x24:
9702 case 0x25:
9703 case 0x26:
9704 case 0x27:
9705 case 0x28:
9706 case 0x29:
9707 case 0x2A:
9708 case 0x2B:
9709 case 0x2C:
9710 case 0x2D:
9711 case 0x2E:
9712 case 0x2F:
9713 case 0x30:
9714 case 0x31:
9715 case 0x32:
9716 case 0x33:
9717 case 0x34:
9718 case 0x35:
9719 case 0x36:
9720 case 0x37:
9721 case 0x38:
9722 case 0x39:
9723 case 0x3A:
9724 case 0x3B:
9725 case 0x3C:
9726 case 0x3D:
9727 case 0x3E:
9728 case 0x3F:
9729 case 0x40:
9730 case 0x41:
9731 case 0x42:
9732 case 0x43:
9733 case 0x44:
9734 case 0x45:
9735 case 0x46:
9736 case 0x47:
9737 case 0x48:
9738 case 0x49:
9739 case 0x4A:
9740 case 0x4B:
9741 case 0x4C:
9742 case 0x4D:
9743 case 0x4E:
9744 case 0x4F:
9745 case 0x50:
9746 case 0x51:
9747 case 0x52:
9748 case 0x53:
9749 case 0x54:
9750 case 0x55:
9751 case 0x56:
9752 case 0x57:
9753 case 0x58:
9754 case 0x59:
9755 case 0x5A:
9756 case 0x5B:
9757 case 0x5C:
9758 case 0x5D:
9759 case 0x5E:
9760 case 0x5F:
9761 case 0x60:
9762 case 0x61:
9763 case 0x62:
9764 case 0x63:
9765 case 0x64:
9766 case 0x65:
9767 case 0x66:
9768 case 0x67:
9769 case 0x68:
9770 case 0x69:
9771 case 0x6A:
9772 case 0x6B:
9773 case 0x6C:
9774 case 0x6D:
9775 case 0x6E:
9776 case 0x6F:
9777 case 0x70:
9778 case 0x71:
9779 case 0x72:
9780 case 0x73:
9781 case 0x74:
9782 case 0x75:
9783 case 0x76:
9784 case 0x77:
9785 case 0x78:
9786 case 0x79:
9787 case 0x7A:
9788 case 0x7B:
9789 case 0x7C:
9790 case 0x7D:
9791 case 0x7E:
9792 case 0x7F:
9793 return sax->number_unsigned(static_cast<number_unsigned_t>(current));
9794
9795 // fixmap
9796 case 0x80:
9797 case 0x81:
9798 case 0x82:
9799 case 0x83:
9800 case 0x84:
9801 case 0x85:
9802 case 0x86:
9803 case 0x87:
9804 case 0x88:
9805 case 0x89:
9806 case 0x8A:
9807 case 0x8B:
9808 case 0x8C:
9809 case 0x8D:
9810 case 0x8E:
9811 case 0x8F:
9812 return get_msgpack_object(static_cast<std::size_t>(static_cast<unsigned int>(current) & 0x0Fu));
9813
9814 // fixarray
9815 case 0x90:
9816 case 0x91:
9817 case 0x92:
9818 case 0x93:
9819 case 0x94:
9820 case 0x95:
9821 case 0x96:
9822 case 0x97:
9823 case 0x98:
9824 case 0x99:
9825 case 0x9A:
9826 case 0x9B:
9827 case 0x9C:
9828 case 0x9D:
9829 case 0x9E:
9830 case 0x9F:
9831 return get_msgpack_array(static_cast<std::size_t>(static_cast<unsigned int>(current) & 0x0Fu));
9832
9833 // fixstr
9834 case 0xA0:
9835 case 0xA1:
9836 case 0xA2:
9837 case 0xA3:
9838 case 0xA4:
9839 case 0xA5:
9840 case 0xA6:
9841 case 0xA7:
9842 case 0xA8:
9843 case 0xA9:
9844 case 0xAA:
9845 case 0xAB:
9846 case 0xAC:
9847 case 0xAD:
9848 case 0xAE:
9849 case 0xAF:
9850 case 0xB0:
9851 case 0xB1:
9852 case 0xB2:
9853 case 0xB3:
9854 case 0xB4:
9855 case 0xB5:
9856 case 0xB6:
9857 case 0xB7:
9858 case 0xB8:
9859 case 0xB9:
9860 case 0xBA:
9861 case 0xBB:
9862 case 0xBC:
9863 case 0xBD:
9864 case 0xBE:
9865 case 0xBF:
9866 case 0xD9: // str 8
9867 case 0xDA: // str 16
9868 case 0xDB: // str 32
9869 {
9870 string_t s;
9871 return get_msgpack_string(s) && sax->string(s);
9872 }
9873
9874 case 0xC0: // nil
9875 return sax->null();
9876
9877 case 0xC2: // false
9878 return sax->boolean(false);
9879
9880 case 0xC3: // true
9881 return sax->boolean(true);
9882
9883 case 0xC4: // bin 8
9884 case 0xC5: // bin 16
9885 case 0xC6: // bin 32
9886 case 0xC7: // ext 8
9887 case 0xC8: // ext 16
9888 case 0xC9: // ext 32
9889 case 0xD4: // fixext 1
9890 case 0xD5: // fixext 2
9891 case 0xD6: // fixext 4
9892 case 0xD7: // fixext 8
9893 case 0xD8: // fixext 16
9894 {
9895 binary_t b;
9896 return get_msgpack_binary(b) && sax->binary(b);
9897 }
9898
9899 case 0xCA: // float 32
9900 {
9901 float number{};
9902 return get_number(input_format_t::msgpack, number) && sax->number_float(static_cast<number_float_t>(number), "");
9903 }
9904
9905 case 0xCB: // float 64
9906 {
9907 double number{};
9908 return get_number(input_format_t::msgpack, number) && sax->number_float(static_cast<number_float_t>(number), "");
9909 }
9910
9911 case 0xCC: // uint 8
9912 {
9913 std::uint8_t number{};
9914 return get_number(input_format_t::msgpack, number) && sax->number_unsigned(number);
9915 }
9916
9917 case 0xCD: // uint 16
9918 {
9919 std::uint16_t number{};
9920 return get_number(input_format_t::msgpack, number) && sax->number_unsigned(number);
9921 }
9922
9923 case 0xCE: // uint 32
9924 {
9925 std::uint32_t number{};
9926 return get_number(input_format_t::msgpack, number) && sax->number_unsigned(number);
9927 }
9928
9929 case 0xCF: // uint 64
9930 {
9931 std::uint64_t number{};
9932 return get_number(input_format_t::msgpack, number) && sax->number_unsigned(number);
9933 }
9934
9935 case 0xD0: // int 8
9936 {
9937 std::int8_t number{};
9938 return get_number(input_format_t::msgpack, number) && sax->number_integer(number);
9939 }
9940
9941 case 0xD1: // int 16
9942 {
9943 std::int16_t number{};
9944 return get_number(input_format_t::msgpack, number) && sax->number_integer(number);
9945 }
9946
9947 case 0xD2: // int 32
9948 {
9949 std::int32_t number{};
9950 return get_number(input_format_t::msgpack, number) && sax->number_integer(number);
9951 }
9952
9953 case 0xD3: // int 64
9954 {
9955 std::int64_t number{};
9956 return get_number(input_format_t::msgpack, number) && sax->number_integer(number);
9957 }
9958
9959 case 0xDC: // array 16
9960 {
9961 std::uint16_t len{};
9962 return get_number(input_format_t::msgpack, len) && get_msgpack_array(static_cast<std::size_t>(len));
9963 }
9964
9965 case 0xDD: // array 32
9966 {
9967 std::uint32_t len{};
9968 return get_number(input_format_t::msgpack, len) && get_msgpack_array(static_cast<std::size_t>(len));
9969 }
9970
9971 case 0xDE: // map 16
9972 {
9973 std::uint16_t len{};
9974 return get_number(input_format_t::msgpack, len) && get_msgpack_object(static_cast<std::size_t>(len));
9975 }
9976
9977 case 0xDF: // map 32
9978 {
9979 std::uint32_t len{};
9980 return get_number(input_format_t::msgpack, len) && get_msgpack_object(static_cast<std::size_t>(len));
9981 }
9982
9983 // negative fixint
9984 case 0xE0:
9985 case 0xE1:
9986 case 0xE2:
9987 case 0xE3:
9988 case 0xE4:
9989 case 0xE5:
9990 case 0xE6:
9991 case 0xE7:
9992 case 0xE8:
9993 case 0xE9:
9994 case 0xEA:
9995 case 0xEB:
9996 case 0xEC:
9997 case 0xED:
9998 case 0xEE:
9999 case 0xEF:
10000 case 0xF0:
10001 case 0xF1:
10002 case 0xF2:
10003 case 0xF3:
10004 case 0xF4:
10005 case 0xF5:
10006 case 0xF6:
10007 case 0xF7:
10008 case 0xF8:
10009 case 0xF9:
10010 case 0xFA:
10011 case 0xFB:
10012 case 0xFC:
10013 case 0xFD:
10014 case 0xFE:
10015 case 0xFF:
10016 return sax->number_integer(static_cast<std::int8_t>(current));
10017
10018 default: // anything else
10019 {
10020 auto last_token = get_token_string();
10021 return sax->parse_error(chars_read, last_token, parse_error::create(112, chars_read,
10022 exception_message(input_format_t::msgpack, concat("invalid byte: 0x", last_token), "value"), nullptr));
10023 }
10024 }
10025 }
10026
10037 bool get_msgpack_string(string_t& result)
10038 {
10039 if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format_t::msgpack, "string")))
10040 {
10041 return false;
10042 }
10043
10044 switch (current)
10045 {
10046 // fixstr
10047 case 0xA0:
10048 case 0xA1:
10049 case 0xA2:
10050 case 0xA3:
10051 case 0xA4:
10052 case 0xA5:
10053 case 0xA6:
10054 case 0xA7:
10055 case 0xA8:
10056 case 0xA9:
10057 case 0xAA:
10058 case 0xAB:
10059 case 0xAC:
10060 case 0xAD:
10061 case 0xAE:
10062 case 0xAF:
10063 case 0xB0:
10064 case 0xB1:
10065 case 0xB2:
10066 case 0xB3:
10067 case 0xB4:
10068 case 0xB5:
10069 case 0xB6:
10070 case 0xB7:
10071 case 0xB8:
10072 case 0xB9:
10073 case 0xBA:
10074 case 0xBB:
10075 case 0xBC:
10076 case 0xBD:
10077 case 0xBE:
10078 case 0xBF:
10079 {
10080 return get_string(input_format_t::msgpack, static_cast<unsigned int>(current) & 0x1Fu, result);
10081 }
10082
10083 case 0xD9: // str 8
10084 {
10085 std::uint8_t len{};
10086 return get_number(input_format_t::msgpack, len) && get_string(input_format_t::msgpack, len, result);
10087 }
10088
10089 case 0xDA: // str 16
10090 {
10091 std::uint16_t len{};
10092 return get_number(input_format_t::msgpack, len) && get_string(input_format_t::msgpack, len, result);
10093 }
10094
10095 case 0xDB: // str 32
10096 {
10097 std::uint32_t len{};
10098 return get_number(input_format_t::msgpack, len) && get_string(input_format_t::msgpack, len, result);
10099 }
10100
10101 default:
10102 {
10103 auto last_token = get_token_string();
10104 return sax->parse_error(chars_read, last_token, parse_error::create(113, chars_read,
10105 exception_message(input_format_t::msgpack, concat("expected length specification (0xA0-0xBF, 0xD9-0xDB); last byte: 0x", last_token), "string"), nullptr));
10106 }
10107 }
10108 }
10109
10120 bool get_msgpack_binary(binary_t& result)
10121 {
10122 // helper function to set the subtype
10123 auto assign_and_return_true = [&result](std::int8_t subtype)
10124 {
10125 result.set_subtype(static_cast<std::uint8_t>(subtype));
10126 return true;
10127 };
10128
10129 switch (current)
10130 {
10131 case 0xC4: // bin 8
10132 {
10133 std::uint8_t len{};
10134 return get_number(input_format_t::msgpack, len) &&
10135 get_binary(input_format_t::msgpack, len, result);
10136 }
10137
10138 case 0xC5: // bin 16
10139 {
10140 std::uint16_t len{};
10141 return get_number(input_format_t::msgpack, len) &&
10142 get_binary(input_format_t::msgpack, len, result);
10143 }
10144
10145 case 0xC6: // bin 32
10146 {
10147 std::uint32_t len{};
10148 return get_number(input_format_t::msgpack, len) &&
10149 get_binary(input_format_t::msgpack, len, result);
10150 }
10151
10152 case 0xC7: // ext 8
10153 {
10154 std::uint8_t len{};
10155 std::int8_t subtype{};
10156 return get_number(input_format_t::msgpack, len) &&
10157 get_number(input_format_t::msgpack, subtype) &&
10158 get_binary(input_format_t::msgpack, len, result) &&
10159 assign_and_return_true(subtype);
10160 }
10161
10162 case 0xC8: // ext 16
10163 {
10164 std::uint16_t len{};
10165 std::int8_t subtype{};
10166 return get_number(input_format_t::msgpack, len) &&
10167 get_number(input_format_t::msgpack, subtype) &&
10168 get_binary(input_format_t::msgpack, len, result) &&
10169 assign_and_return_true(subtype);
10170 }
10171
10172 case 0xC9: // ext 32
10173 {
10174 std::uint32_t len{};
10175 std::int8_t subtype{};
10176 return get_number(input_format_t::msgpack, len) &&
10177 get_number(input_format_t::msgpack, subtype) &&
10178 get_binary(input_format_t::msgpack, len, result) &&
10179 assign_and_return_true(subtype);
10180 }
10181
10182 case 0xD4: // fixext 1
10183 {
10184 std::int8_t subtype{};
10185 return get_number(input_format_t::msgpack, subtype) &&
10186 get_binary(input_format_t::msgpack, 1, result) &&
10187 assign_and_return_true(subtype);
10188 }
10189
10190 case 0xD5: // fixext 2
10191 {
10192 std::int8_t subtype{};
10193 return get_number(input_format_t::msgpack, subtype) &&
10194 get_binary(input_format_t::msgpack, 2, result) &&
10195 assign_and_return_true(subtype);
10196 }
10197
10198 case 0xD6: // fixext 4
10199 {
10200 std::int8_t subtype{};
10201 return get_number(input_format_t::msgpack, subtype) &&
10202 get_binary(input_format_t::msgpack, 4, result) &&
10203 assign_and_return_true(subtype);
10204 }
10205
10206 case 0xD7: // fixext 8
10207 {
10208 std::int8_t subtype{};
10209 return get_number(input_format_t::msgpack, subtype) &&
10210 get_binary(input_format_t::msgpack, 8, result) &&
10211 assign_and_return_true(subtype);
10212 }
10213
10214 case 0xD8: // fixext 16
10215 {
10216 std::int8_t subtype{};
10217 return get_number(input_format_t::msgpack, subtype) &&
10218 get_binary(input_format_t::msgpack, 16, result) &&
10219 assign_and_return_true(subtype);
10220 }
10221
10222 default: // LCOV_EXCL_LINE
10223 return false; // LCOV_EXCL_LINE
10224 }
10225 }
10226
10231 bool get_msgpack_array(const std::size_t len)
10232 {
10233 if (JSON_HEDLEY_UNLIKELY(!sax->start_array(len)))
10234 {
10235 return false;
10236 }
10237
10238 for (std::size_t i = 0; i < len; ++i)
10239 {
10240 if (JSON_HEDLEY_UNLIKELY(!parse_msgpack_internal()))
10241 {
10242 return false;
10243 }
10244 }
10245
10246 return sax->end_array();
10247 }
10248
10253 bool get_msgpack_object(const std::size_t len)
10254 {
10255 if (JSON_HEDLEY_UNLIKELY(!sax->start_object(len)))
10256 {
10257 return false;
10258 }
10259
10260 string_t key;
10261 for (std::size_t i = 0; i < len; ++i)
10262 {
10263 get();
10264 if (JSON_HEDLEY_UNLIKELY(!get_msgpack_string(key) || !sax->key(key)))
10265 {
10266 return false;
10267 }
10268
10269 if (JSON_HEDLEY_UNLIKELY(!parse_msgpack_internal()))
10270 {
10271 return false;
10272 }
10273 key.clear();
10274 }
10275
10276 return sax->end_object();
10277 }
10278
10280 // UBJSON //
10282
10290 bool parse_ubjson_internal(const bool get_char = true)
10291 {
10292 return get_ubjson_value(get_char ? get_ignore_noop() : current);
10293 }
10294
10309 bool get_ubjson_string(string_t& result, const bool get_char = true)
10310 {
10311 if (get_char)
10312 {
10313 get(); // TODO(niels): may we ignore N here?
10314 }
10315
10316 if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format, "value")))
10317 {
10318 return false;
10319 }
10320
10321 switch (current)
10322 {
10323 case 'U':
10324 {
10325 std::uint8_t len{};
10326 return get_number(input_format, len) && get_string(input_format, len, result);
10327 }
10328
10329 case 'i':
10330 {
10331 std::int8_t len{};
10332 return get_number(input_format, len) && get_string(input_format, len, result);
10333 }
10334
10335 case 'I':
10336 {
10337 std::int16_t len{};
10338 return get_number(input_format, len) && get_string(input_format, len, result);
10339 }
10340
10341 case 'l':
10342 {
10343 std::int32_t len{};
10344 return get_number(input_format, len) && get_string(input_format, len, result);
10345 }
10346
10347 case 'L':
10348 {
10349 std::int64_t len{};
10350 return get_number(input_format, len) && get_string(input_format, len, result);
10351 }
10352
10353 case 'u':
10354 {
10355 if (input_format != input_format_t::bjdata)
10356 {
10357 break;
10358 }
10359 std::uint16_t len{};
10360 return get_number(input_format, len) && get_string(input_format, len, result);
10361 }
10362
10363 case 'm':
10364 {
10365 if (input_format != input_format_t::bjdata)
10366 {
10367 break;
10368 }
10369 std::uint32_t len{};
10370 return get_number(input_format, len) && get_string(input_format, len, result);
10371 }
10372
10373 case 'M':
10374 {
10375 if (input_format != input_format_t::bjdata)
10376 {
10377 break;
10378 }
10379 std::uint64_t len{};
10380 return get_number(input_format, len) && get_string(input_format, len, result);
10381 }
10382
10383 default:
10384 break;
10385 }
10386 auto last_token = get_token_string();
10387 std::string message;
10388
10389 if (input_format != input_format_t::bjdata)
10390 {
10391 message = "expected length type specification (U, i, I, l, L); last byte: 0x" + last_token;
10392 }
10393 else
10394 {
10395 message = "expected length type specification (U, i, u, I, m, l, M, L); last byte: 0x" + last_token;
10396 }
10397 return sax->parse_error(chars_read, last_token, parse_error::create(113, chars_read, exception_message(input_format, message, "string"), nullptr));
10398 }
10399
10404 bool get_ubjson_ndarray_size(std::vector<size_t>& dim)
10405 {
10406 std::pair<std::size_t, char_int_type> size_and_type;
10407 size_t dimlen = 0;
10408
10409 if (JSON_HEDLEY_UNLIKELY(!get_ubjson_size_type(size_and_type)))
10410 {
10411 return false;
10412 }
10413
10414 if (size_and_type.first != string_t::npos)
10415 {
10416 if (size_and_type.second != 0)
10417 {
10418 if (size_and_type.second != 'N')
10419 {
10420 for (std::size_t i = 0; i < size_and_type.first; ++i)
10421 {
10422 if (JSON_HEDLEY_UNLIKELY(!get_ubjson_size_value(dimlen, size_and_type.second)))
10423 {
10424 return false;
10425 }
10426 dim.push_back(dimlen);
10427 }
10428 }
10429 }
10430 else
10431 {
10432 for (std::size_t i = 0; i < size_and_type.first; ++i)
10433 {
10434 if (JSON_HEDLEY_UNLIKELY(!get_ubjson_size_value(dimlen)))
10435 {
10436 return false;
10437 }
10438 dim.push_back(dimlen);
10439 }
10440 }
10441 }
10442 else
10443 {
10444 while (current != ']')
10445 {
10446 if (JSON_HEDLEY_UNLIKELY(!get_ubjson_size_value(dimlen, current)))
10447 {
10448 return false;
10449 }
10450 dim.push_back(dimlen);
10451 get_ignore_noop();
10452 }
10453 }
10454 return true;
10455 }
10456
10461 bool get_ubjson_size_value(std::size_t& result, char_int_type prefix = 0)
10462 {
10463 if (prefix == 0)
10464 {
10465 prefix = get_ignore_noop();
10466 }
10467
10468 switch (prefix)
10469 {
10470 case 'U':
10471 {
10472 std::uint8_t number{};
10473 if (JSON_HEDLEY_UNLIKELY(!get_number(input_format, number)))
10474 {
10475 return false;
10476 }
10477 result = static_cast<std::size_t>(number);
10478 return true;
10479 }
10480
10481 case 'i':
10482 {
10483 std::int8_t number{};
10484 if (JSON_HEDLEY_UNLIKELY(!get_number(input_format, number)))
10485 {
10486 return false;
10487 }
10488 result = static_cast<std::size_t>(number); // NOLINT(bugprone-signed-char-misuse,cert-str34-c): number is not a char
10489 return true;
10490 }
10491
10492 case 'I':
10493 {
10494 std::int16_t number{};
10495 if (JSON_HEDLEY_UNLIKELY(!get_number(input_format, number)))
10496 {
10497 return false;
10498 }
10499 result = static_cast<std::size_t>(number);
10500 return true;
10501 }
10502
10503 case 'l':
10504 {
10505 std::int32_t number{};
10506 if (JSON_HEDLEY_UNLIKELY(!get_number(input_format, number)))
10507 {
10508 return false;
10509 }
10510 result = static_cast<std::size_t>(number);
10511 return true;
10512 }
10513
10514 case 'L':
10515 {
10516 std::int64_t number{};
10517 if (JSON_HEDLEY_UNLIKELY(!get_number(input_format, number)))
10518 {
10519 return false;
10520 }
10521 result = static_cast<std::size_t>(number);
10522 return true;
10523 }
10524
10525 case 'u':
10526 {
10527 if (input_format != input_format_t::bjdata)
10528 {
10529 break;
10530 }
10531 std::uint16_t number{};
10532 if (JSON_HEDLEY_UNLIKELY(!get_number(input_format, number)))
10533 {
10534 return false;
10535 }
10536 result = static_cast<std::size_t>(number);
10537 return true;
10538 }
10539
10540 case 'm':
10541 {
10542 if (input_format != input_format_t::bjdata)
10543 {
10544 break;
10545 }
10546 std::uint32_t number{};
10547 if (JSON_HEDLEY_UNLIKELY(!get_number(input_format, number)))
10548 {
10549 return false;
10550 }
10551 result = static_cast<std::size_t>(number);
10552 return true;
10553 }
10554
10555 case 'M':
10556 {
10557 if (input_format != input_format_t::bjdata)
10558 {
10559 break;
10560 }
10561 std::uint64_t number{};
10562 if (JSON_HEDLEY_UNLIKELY(!get_number(input_format, number)))
10563 {
10564 return false;
10565 }
10566 result = detail::conditional_static_cast<std::size_t>(number);
10567 return true;
10568 }
10569
10570 case '[':
10571 {
10572 if (input_format != input_format_t::bjdata)
10573 {
10574 break;
10575 }
10576 std::vector<size_t> dim;
10577 if (JSON_HEDLEY_UNLIKELY(!get_ubjson_ndarray_size(dim)))
10578 {
10579 return false;
10580 }
10581 if (dim.size() == 1 || (dim.size() == 2 && dim.at(0) == 1)) // return normal array size if 1D row vector
10582 {
10583 result = dim.at(dim.size() - 1);
10584 return true;
10585 }
10586 if (!dim.empty()) // if ndarray, convert to an object in JData annotated array format
10587 {
10588 string_t key = "_ArraySize_";
10589 if (JSON_HEDLEY_UNLIKELY(!sax->start_object(3) || !sax->key(key) || !sax->start_array(dim.size())))
10590 {
10591 return false;
10592 }
10593 result = 1;
10594 for (auto i : dim)
10595 {
10596 result *= i;
10597 if (JSON_HEDLEY_UNLIKELY(!sax->number_integer(static_cast<number_integer_t>(i))))
10598 {
10599 return false;
10600 }
10601 }
10602 result |= (1ull << (sizeof(result) * 8 - 1)); // low 63 bit of result stores the total element count, sign-bit indicates ndarray
10603 return sax->end_array();
10604 }
10605 result = 0;
10606 return true;
10607 }
10608
10609 default:
10610 break;
10611 }
10612 auto last_token = get_token_string();
10613 std::string message;
10614
10615 if (input_format != input_format_t::bjdata)
10616 {
10617 message = "expected length type specification (U, i, I, l, L) after '#'; last byte: 0x" + last_token;
10618 }
10619 else
10620 {
10621 message = "expected length type specification (U, i, u, I, m, l, M, L) after '#'; last byte: 0x" + last_token;
10622 }
10623 return sax->parse_error(chars_read, last_token, parse_error::create(113, chars_read, exception_message(input_format, message, "size"), nullptr));
10624 }
10625
10636 bool get_ubjson_size_type(std::pair<std::size_t, char_int_type>& result)
10637 {
10638 result.first = string_t::npos; // size
10639 result.second = 0; // type
10640
10641 get_ignore_noop();
10642
10643 if (current == '$')
10644 {
10645 std::vector<char_int_type> bjdx = {'[', '{', 'S', 'H', 'T', 'F', 'N', 'Z'}; // excluded markers in bjdata optimized type
10646
10647 result.second = get(); // must not ignore 'N', because 'N' maybe the type
10648 if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format, "type") || (input_format == input_format_t::bjdata && std::find(bjdx.begin(), bjdx.end(), result.second) != bjdx.end() )))
10649 {
10650 return false;
10651 }
10652
10653 get_ignore_noop();
10654 if (JSON_HEDLEY_UNLIKELY(current != '#'))
10655 {
10656 if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format, "value")))
10657 {
10658 return false;
10659 }
10660 auto last_token = get_token_string();
10661 return sax->parse_error(chars_read, last_token, parse_error::create(112, chars_read,
10662 exception_message(input_format, concat("expected '#' after type information; last byte: 0x", last_token), "size"), nullptr));
10663 }
10664
10665 return get_ubjson_size_value(result.first);
10666 }
10667
10668 if (current == '#')
10669 {
10670 return get_ubjson_size_value(result.first);
10671 }
10672
10673 return true;
10674 }
10675
10680 bool get_ubjson_value(const char_int_type prefix)
10681 {
10682 switch (prefix)
10683 {
10684 case std::char_traits<char_type>::eof(): // EOF
10685 return unexpect_eof(input_format, "value");
10686
10687 case 'T': // true
10688 return sax->boolean(true);
10689 case 'F': // false
10690 return sax->boolean(false);
10691
10692 case 'Z': // null
10693 return sax->null();
10694
10695 case 'U':
10696 {
10697 std::uint8_t number{};
10698 return get_number(input_format, number) && sax->number_unsigned(number);
10699 }
10700
10701 case 'i':
10702 {
10703 std::int8_t number{};
10704 return get_number(input_format, number) && sax->number_integer(number);
10705 }
10706
10707 case 'I':
10708 {
10709 std::int16_t number{};
10710 return get_number(input_format, number) && sax->number_integer(number);
10711 }
10712
10713 case 'l':
10714 {
10715 std::int32_t number{};
10716 return get_number(input_format, number) && sax->number_integer(number);
10717 }
10718
10719 case 'L':
10720 {
10721 std::int64_t number{};
10722 return get_number(input_format, number) && sax->number_integer(number);
10723 }
10724
10725 case 'u':
10726 {
10727 if (input_format != input_format_t::bjdata)
10728 {
10729 break;
10730 }
10731 std::uint16_t number{};
10732 return get_number(input_format, number) && sax->number_unsigned(number);
10733 }
10734
10735 case 'm':
10736 {
10737 if (input_format != input_format_t::bjdata)
10738 {
10739 break;
10740 }
10741 std::uint32_t number{};
10742 return get_number(input_format, number) && sax->number_unsigned(number);
10743 }
10744
10745 case 'M':
10746 {
10747 if (input_format != input_format_t::bjdata)
10748 {
10749 break;
10750 }
10751 std::uint64_t number{};
10752 return get_number(input_format, number) && sax->number_unsigned(number);
10753 }
10754
10755 case 'h':
10756 {
10757 if (input_format != input_format_t::bjdata)
10758 {
10759 break;
10760 }
10761 const auto byte1_raw = get();
10762 if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format, "number")))
10763 {
10764 return false;
10765 }
10766 const auto byte2_raw = get();
10767 if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format, "number")))
10768 {
10769 return false;
10770 }
10771
10772 const auto byte1 = static_cast<unsigned char>(byte1_raw);
10773 const auto byte2 = static_cast<unsigned char>(byte2_raw);
10774
10775 // code from RFC 7049, Appendix D, Figure 3:
10776 // As half-precision floating-point numbers were only added
10777 // to IEEE 754 in 2008, today's programming platforms often
10778 // still only have limited support for them. It is very
10779 // easy to include at least decoding support for them even
10780 // without such support. An example of a small decoder for
10781 // half-precision floating-point numbers in the C language
10782 // is shown in Fig. 3.
10783 const auto half = static_cast<unsigned int>((byte2 << 8u) + byte1);
10784 const double val = [&half]
10785 {
10786 const int exp = (half >> 10u) & 0x1Fu;
10787 const unsigned int mant = half & 0x3FFu;
10788 JSON_ASSERT(0 <= exp&& exp <= 32);
10789 JSON_ASSERT(mant <= 1024);
10790 switch (exp)
10791 {
10792 case 0:
10793 return std::ldexp(mant, -24);
10794 case 31:
10795 return (mant == 0)
10796 ? std::numeric_limits<double>::infinity()
10797 : std::numeric_limits<double>::quiet_NaN();
10798 default:
10799 return std::ldexp(mant + 1024, exp - 25);
10800 }
10801 }();
10802 return sax->number_float((half & 0x8000u) != 0
10803 ? static_cast<number_float_t>(-val)
10804 : static_cast<number_float_t>(val), "");
10805 }
10806
10807 case 'd':
10808 {
10809 float number{};
10810 return get_number(input_format, number) && sax->number_float(static_cast<number_float_t>(number), "");
10811 }
10812
10813 case 'D':
10814 {
10815 double number{};
10816 return get_number(input_format, number) && sax->number_float(static_cast<number_float_t>(number), "");
10817 }
10818
10819 case 'H':
10820 {
10821 return get_ubjson_high_precision_number();
10822 }
10823
10824 case 'C': // char
10825 {
10826 get();
10827 if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format, "char")))
10828 {
10829 return false;
10830 }
10831 if (JSON_HEDLEY_UNLIKELY(current > 127))
10832 {
10833 auto last_token = get_token_string();
10834 return sax->parse_error(chars_read, last_token, parse_error::create(113, chars_read,
10835 exception_message(input_format, concat("byte after 'C' must be in range 0x00..0x7F; last byte: 0x", last_token), "char"), nullptr));
10836 }
10837 string_t s(1, static_cast<typename string_t::value_type>(current));
10838 return sax->string(s);
10839 }
10840
10841 case 'S': // string
10842 {
10843 string_t s;
10844 return get_ubjson_string(s) && sax->string(s);
10845 }
10846
10847 case '[': // array
10848 return get_ubjson_array();
10849
10850 case '{': // object
10851 return get_ubjson_object();
10852
10853 default: // anything else
10854 break;
10855 }
10856 auto last_token = get_token_string();
10857 return sax->parse_error(chars_read, last_token, parse_error::create(112, chars_read, exception_message(input_format, "invalid byte: 0x" + last_token, "value"), nullptr));
10858 }
10859
10863 bool get_ubjson_array()
10864 {
10865 std::pair<std::size_t, char_int_type> size_and_type;
10866 if (JSON_HEDLEY_UNLIKELY(!get_ubjson_size_type(size_and_type)))
10867 {
10868 return false;
10869 }
10870
10871 // detect and encode bjdata ndarray as an object in JData annotated array format (https://github.com/NeuroJSON/jdata):
10872 // {"_ArrayType_" : "typeid", "_ArraySize_" : [n1, n2, ...], "_ArrayData_" : [v1, v2, ...]}
10873
10874 if (input_format == input_format_t::bjdata && size_and_type.first != string_t::npos && size_and_type.first >= (1ull << (sizeof(std::size_t) * 8 - 1)))
10875 {
10876 std::map<char_int_type, string_t> bjdtype = {{'U', "uint8"}, {'i', "int8"}, {'u', "uint16"}, {'I', "int16"},
10877 {'m', "uint32"}, {'l', "int32"}, {'M', "uint64"}, {'L', "int64"}, {'d', "single"}, {'D', "double"}, {'C', "char"}
10878 };
10879
10880 string_t key = "_ArrayType_";
10881 if (JSON_HEDLEY_UNLIKELY(bjdtype.count(size_and_type.second) == 0 || !sax->key(key) || !sax->string(bjdtype[size_and_type.second]) ))
10882 {
10883 return false;
10884 }
10885
10886 if (size_and_type.second == 'C')
10887 {
10888 size_and_type.second = 'U';
10889 }
10890
10891 size_and_type.first &= ~(1ull << (sizeof(std::size_t) * 8 - 1));
10892 key = "_ArrayData_";
10893 if (JSON_HEDLEY_UNLIKELY(!sax->key(key) || !sax->start_array(size_and_type.first) ))
10894 {
10895 return false;
10896 }
10897
10898 for (std::size_t i = 0; i < size_and_type.first; ++i)
10899 {
10900 if (JSON_HEDLEY_UNLIKELY(!get_ubjson_value(size_and_type.second)))
10901 {
10902 return false;
10903 }
10904 }
10905
10906 return (sax->end_array() && sax->end_object());
10907 }
10908
10909 if (size_and_type.first != string_t::npos)
10910 {
10911 if (JSON_HEDLEY_UNLIKELY(!sax->start_array(size_and_type.first)))
10912 {
10913 return false;
10914 }
10915
10916 if (size_and_type.second != 0)
10917 {
10918 if (size_and_type.second != 'N')
10919 {
10920 for (std::size_t i = 0; i < size_and_type.first; ++i)
10921 {
10922 if (JSON_HEDLEY_UNLIKELY(!get_ubjson_value(size_and_type.second)))
10923 {
10924 return false;
10925 }
10926 }
10927 }
10928 }
10929 else
10930 {
10931 for (std::size_t i = 0; i < size_and_type.first; ++i)
10932 {
10933 if (JSON_HEDLEY_UNLIKELY(!parse_ubjson_internal()))
10934 {
10935 return false;
10936 }
10937 }
10938 }
10939 }
10940 else
10941 {
10942 if (JSON_HEDLEY_UNLIKELY(!sax->start_array(static_cast<std::size_t>(-1))))
10943 {
10944 return false;
10945 }
10946
10947 while (current != ']')
10948 {
10949 if (JSON_HEDLEY_UNLIKELY(!parse_ubjson_internal(false)))
10950 {
10951 return false;
10952 }
10953 get_ignore_noop();
10954 }
10955 }
10956
10957 return sax->end_array();
10958 }
10959
10963 bool get_ubjson_object()
10964 {
10965 std::pair<std::size_t, char_int_type> size_and_type;
10966 if (JSON_HEDLEY_UNLIKELY(!get_ubjson_size_type(size_and_type)))
10967 {
10968 return false;
10969 }
10970
10971 if (input_format == input_format_t::bjdata && size_and_type.first != string_t::npos && size_and_type.first >= (1ull << (sizeof(std::size_t) * 8 - 1)))
10972 {
10973 return false;
10974 }
10975
10976 string_t key;
10977 if (size_and_type.first != string_t::npos)
10978 {
10979 if (JSON_HEDLEY_UNLIKELY(!sax->start_object(size_and_type.first)))
10980 {
10981 return false;
10982 }
10983
10984 if (size_and_type.second != 0)
10985 {
10986 for (std::size_t i = 0; i < size_and_type.first; ++i)
10987 {
10988 if (JSON_HEDLEY_UNLIKELY(!get_ubjson_string(key) || !sax->key(key)))
10989 {
10990 return false;
10991 }
10992 if (JSON_HEDLEY_UNLIKELY(!get_ubjson_value(size_and_type.second)))
10993 {
10994 return false;
10995 }
10996 key.clear();
10997 }
10998 }
10999 else
11000 {
11001 for (std::size_t i = 0; i < size_and_type.first; ++i)
11002 {
11003 if (JSON_HEDLEY_UNLIKELY(!get_ubjson_string(key) || !sax->key(key)))
11004 {
11005 return false;
11006 }
11007 if (JSON_HEDLEY_UNLIKELY(!parse_ubjson_internal()))
11008 {
11009 return false;
11010 }
11011 key.clear();
11012 }
11013 }
11014 }
11015 else
11016 {
11017 if (JSON_HEDLEY_UNLIKELY(!sax->start_object(static_cast<std::size_t>(-1))))
11018 {
11019 return false;
11020 }
11021
11022 while (current != '}')
11023 {
11024 if (JSON_HEDLEY_UNLIKELY(!get_ubjson_string(key, false) || !sax->key(key)))
11025 {
11026 return false;
11027 }
11028 if (JSON_HEDLEY_UNLIKELY(!parse_ubjson_internal()))
11029 {
11030 return false;
11031 }
11032 get_ignore_noop();
11033 key.clear();
11034 }
11035 }
11036
11037 return sax->end_object();
11038 }
11039
11040 // Note, no reader for UBJSON binary types is implemented because they do
11041 // not exist
11042
11043 bool get_ubjson_high_precision_number()
11044 {
11045 // get size of following number string
11046 std::size_t size{};
11047 auto res = get_ubjson_size_value(size);
11049 {
11050 return res;
11051 }
11052
11053 // get number string
11054 std::vector<char> number_vector;
11055 for (std::size_t i = 0; i < size; ++i)
11056 {
11057 get();
11058 if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format, "number")))
11059 {
11060 return false;
11061 }
11062 number_vector.push_back(static_cast<char>(current));
11063 }
11064
11065 // parse number string
11066 using ia_type = decltype(detail::input_adapter(number_vector));
11067 auto number_lexer = detail::lexer<BasicJsonType, ia_type>(detail::input_adapter(number_vector), false);
11068 const auto result_number = number_lexer.scan();
11069 const auto number_string = number_lexer.get_token_string();
11070 const auto result_remainder = number_lexer.scan();
11071
11072 using token_type = typename detail::lexer_base<BasicJsonType>::token_type;
11073
11074 if (JSON_HEDLEY_UNLIKELY(result_remainder != token_type::end_of_input))
11075 {
11076 return sax->parse_error(chars_read, number_string, parse_error::create(115, chars_read,
11077 exception_message(input_format, concat("invalid number text: ", number_lexer.get_token_string()), "high-precision number"), nullptr));
11078 }
11079
11080 switch (result_number)
11081 {
11082 case token_type::value_integer:
11083 return sax->number_integer(number_lexer.get_number_integer());
11084 case token_type::value_unsigned:
11085 return sax->number_unsigned(number_lexer.get_number_unsigned());
11086 case token_type::value_float:
11087 return sax->number_float(number_lexer.get_number_float(), std::move(number_string));
11088 case token_type::uninitialized:
11089 case token_type::literal_true:
11090 case token_type::literal_false:
11091 case token_type::literal_null:
11092 case token_type::value_string:
11093 case token_type::begin_array:
11094 case token_type::begin_object:
11095 case token_type::end_array:
11096 case token_type::end_object:
11097 case token_type::name_separator:
11098 case token_type::value_separator:
11099 case token_type::parse_error:
11100 case token_type::end_of_input:
11101 case token_type::literal_or_value:
11102 default:
11103 return sax->parse_error(chars_read, number_string, parse_error::create(115, chars_read,
11104 exception_message(input_format, concat("invalid number text: ", number_lexer.get_token_string()), "high-precision number"), nullptr));
11105 }
11106 }
11107
11109 // Utility functions //
11111
11121 char_int_type get()
11122 {
11123 ++chars_read;
11124 return current = ia.get_character();
11125 }
11126
11130 char_int_type get_ignore_noop()
11131 {
11132 do
11133 {
11134 get();
11135 }
11136 while (current == 'N');
11137
11138 return current;
11139 }
11140
11141 /*
11142 @brief read a number from the input
11143
11144 @tparam NumberType the type of the number
11145 @param[in] format the current format (for diagnostics)
11146 @param[out] result number of type @a NumberType
11147
11148 @return whether conversion completed
11149
11150 @note This function needs to respect the system's endianness, because
11151 bytes in CBOR, MessagePack, and UBJSON are stored in network order
11152 (big endian) and therefore need reordering on little endian systems.
11153 On the other hand, BSON and BJData use little endian and should reorder
11154 on big endian systems.
11155 */
11156 template<typename NumberType, bool InputIsLittleEndian = false>
11157 bool get_number(const input_format_t format, NumberType& result)
11158 {
11159 // step 1: read input into array with system's byte order
11160 std::array<std::uint8_t, sizeof(NumberType)> vec{};
11161 for (std::size_t i = 0; i < sizeof(NumberType); ++i)
11162 {
11163 get();
11164 if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(format, "number")))
11165 {
11166 return false;
11167 }
11168
11169 // reverse byte order prior to conversion if necessary
11170 if (is_little_endian != (InputIsLittleEndian || format == input_format_t::bjdata))
11171 {
11172 vec[sizeof(NumberType) - i - 1] = static_cast<std::uint8_t>(current);
11173 }
11174 else
11175 {
11176 vec[i] = static_cast<std::uint8_t>(current); // LCOV_EXCL_LINE
11177 }
11178 }
11179
11180 // step 2: convert array into number of type T and return
11181 std::memcpy(&result, vec.data(), sizeof(NumberType));
11182 return true;
11183 }
11184
11199 template<typename NumberType>
11200 bool get_string(const input_format_t format,
11201 const NumberType len,
11202 string_t& result)
11203 {
11204 bool success = true;
11205 for (NumberType i = 0; i < len; i++)
11206 {
11207 get();
11208 if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(format, "string")))
11209 {
11210 success = false;
11211 break;
11212 }
11213 result.push_back(static_cast<typename string_t::value_type>(current));
11214 }
11215 return success;
11216 }
11217
11232 template<typename NumberType>
11233 bool get_binary(const input_format_t format,
11234 const NumberType len,
11235 binary_t& result)
11236 {
11237 bool success = true;
11238 for (NumberType i = 0; i < len; i++)
11239 {
11240 get();
11241 if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(format, "binary")))
11242 {
11243 success = false;
11244 break;
11245 }
11246 result.push_back(static_cast<std::uint8_t>(current));
11247 }
11248 return success;
11249 }
11250
11257 bool unexpect_eof(const input_format_t format, const char* context) const
11258 {
11259 if (JSON_HEDLEY_UNLIKELY(current == std::char_traits<char_type>::eof()))
11260 {
11261 return sax->parse_error(chars_read, "<end of file>",
11262 parse_error::create(110, chars_read, exception_message(format, "unexpected end of input", context), nullptr));
11263 }
11264 return true;
11265 }
11266
11270 std::string get_token_string() const
11271 {
11272 std::array<char, 3> cr{{}};
11273 static_cast<void>((std::snprintf)(cr.data(), cr.size(), "%.2hhX", static_cast<unsigned char>(current))); // NOLINT(cppcoreguidelines-pro-type-vararg,hicpp-vararg)
11274 return std::string{cr.data()};
11275 }
11276
11283 std::string exception_message(const input_format_t format,
11284 const std::string& detail,
11285 const std::string& context) const
11286 {
11287 std::string error_msg = "syntax error while parsing ";
11288
11289 switch (format)
11290 {
11291 case input_format_t::cbor:
11292 error_msg += "CBOR";
11293 break;
11294
11295 case input_format_t::msgpack:
11296 error_msg += "MessagePack";
11297 break;
11298
11299 case input_format_t::ubjson:
11300 error_msg += "UBJSON";
11301 break;
11302
11303 case input_format_t::bson:
11304 error_msg += "BSON";
11305 break;
11306
11307 case input_format_t::bjdata:
11308 error_msg += "BJData";
11309 break;
11310
11311 case input_format_t::json: // LCOV_EXCL_LINE
11312 default: // LCOV_EXCL_LINE
11313 JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert) LCOV_EXCL_LINE
11314 }
11315
11316 return concat(error_msg, ' ', context, ": ", detail);
11317 }
11318
11319 private:
11321 InputAdapterType ia;
11322
11324 char_int_type current = std::char_traits<char_type>::eof();
11325
11327 std::size_t chars_read = 0;
11328
11330 const bool is_little_endian = little_endianness();
11331
11333 const input_format_t input_format = input_format_t::json;
11334
11336 json_sax_t* sax = nullptr;
11337};
11338} // namespace detail
11339} // namespace nlohmann
11340
11341// #include <nlohmann/detail/input/input_adapters.hpp>
11342
11343// #include <nlohmann/detail/input/lexer.hpp>
11344
11345// #include <nlohmann/detail/input/parser.hpp>
11346
11347
11348#include <cmath> // isfinite
11349#include <cstdint> // uint8_t
11350#include <functional> // function
11351#include <string> // string
11352#include <utility> // move
11353#include <vector> // vector
11354
11355// #include <nlohmann/detail/exceptions.hpp>
11356
11357// #include <nlohmann/detail/input/input_adapters.hpp>
11358
11359// #include <nlohmann/detail/input/json_sax.hpp>
11360
11361// #include <nlohmann/detail/input/lexer.hpp>
11362
11363// #include <nlohmann/detail/macro_scope.hpp>
11364
11365// #include <nlohmann/detail/meta/is_sax.hpp>
11366
11367// #include <nlohmann/detail/string_concat.hpp>
11368
11369// #include <nlohmann/detail/value_t.hpp>
11370
11371
11372namespace nlohmann
11373{
11374namespace detail
11375{
11377// parser //
11379
11380enum class parse_event_t : std::uint8_t
11381{
11383 object_start,
11385 object_end,
11387 array_start,
11389 array_end,
11391 key,
11393 value
11394};
11395
11396template<typename BasicJsonType>
11397using parser_callback_t =
11398 std::function<bool(int /*depth*/, parse_event_t /*event*/, BasicJsonType& /*parsed*/)>;
11399
11405template<typename BasicJsonType, typename InputAdapterType>
11406class parser
11407{
11408 using number_integer_t = typename BasicJsonType::number_integer_t;
11409 using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
11410 using number_float_t = typename BasicJsonType::number_float_t;
11411 using string_t = typename BasicJsonType::string_t;
11412 using lexer_t = lexer<BasicJsonType, InputAdapterType>;
11413 using token_type = typename lexer_t::token_type;
11414
11415 public:
11417 explicit parser(InputAdapterType&& adapter,
11418 const parser_callback_t<BasicJsonType> cb = nullptr,
11419 const bool allow_exceptions_ = true,
11420 const bool skip_comments = false)
11421 : callback(cb)
11422 , m_lexer(std::move(adapter), skip_comments)
11423 , allow_exceptions(allow_exceptions_)
11424 {
11425 // read first token
11426 get_token();
11427 }
11428
11439 void parse(const bool strict, BasicJsonType& result)
11440 {
11441 if (callback)
11442 {
11443 json_sax_dom_callback_parser<BasicJsonType> sdp(result, callback, allow_exceptions);
11444 sax_parse_internal(&sdp);
11445
11446 // in strict mode, input must be completely read
11447 if (strict && (get_token() != token_type::end_of_input))
11448 {
11449 sdp.parse_error(m_lexer.get_position(),
11450 m_lexer.get_token_string(),
11451 parse_error::create(101, m_lexer.get_position(),
11452 exception_message(token_type::end_of_input, "value"), nullptr));
11453 }
11454
11455 // in case of an error, return discarded value
11456 if (sdp.is_errored())
11457 {
11459 return;
11460 }
11461
11462 // set top-level value to null if it was discarded by the callback
11463 // function
11464 if (result.is_discarded())
11465 {
11466 result = nullptr;
11467 }
11468 }
11469 else
11470 {
11471 json_sax_dom_parser<BasicJsonType> sdp(result, allow_exceptions);
11472 sax_parse_internal(&sdp);
11473
11474 // in strict mode, input must be completely read
11475 if (strict && (get_token() != token_type::end_of_input))
11476 {
11477 sdp.parse_error(m_lexer.get_position(),
11478 m_lexer.get_token_string(),
11479 parse_error::create(101, m_lexer.get_position(), exception_message(token_type::end_of_input, "value"), nullptr));
11480 }
11481
11482 // in case of an error, return discarded value
11483 if (sdp.is_errored())
11484 {
11486 return;
11487 }
11488 }
11489
11490 result.assert_invariant();
11491 }
11492
11499 bool accept(const bool strict = true)
11500 {
11501 json_sax_acceptor<BasicJsonType> sax_acceptor;
11502 return sax_parse(&sax_acceptor, strict);
11503 }
11504
11505 template<typename SAX>
11507 bool sax_parse(SAX* sax, const bool strict = true)
11508 {
11509 (void)detail::is_sax_static_asserts<SAX, BasicJsonType> {};
11510 const bool result = sax_parse_internal(sax);
11511
11512 // strict mode: next byte must be EOF
11513 if (result && strict && (get_token() != token_type::end_of_input))
11514 {
11515 return sax->parse_error(m_lexer.get_position(),
11516 m_lexer.get_token_string(),
11517 parse_error::create(101, m_lexer.get_position(), exception_message(token_type::end_of_input, "value"), nullptr));
11518 }
11519
11520 return result;
11521 }
11522
11523 private:
11524 template<typename SAX>
11526 bool sax_parse_internal(SAX* sax)
11527 {
11528 // stack to remember the hierarchy of structured values we are parsing
11529 // true = array; false = object
11530 std::vector<bool> states;
11531 // value to avoid a goto (see comment where set to true)
11532 bool skip_to_state_evaluation = false;
11533
11534 while (true)
11535 {
11536 if (!skip_to_state_evaluation)
11537 {
11538 // invariant: get_token() was called before each iteration
11539 switch (last_token)
11540 {
11541 case token_type::begin_object:
11542 {
11543 if (JSON_HEDLEY_UNLIKELY(!sax->start_object(static_cast<std::size_t>(-1))))
11544 {
11545 return false;
11546 }
11547
11548 // closing } -> we are done
11549 if (get_token() == token_type::end_object)
11550 {
11551 if (JSON_HEDLEY_UNLIKELY(!sax->end_object()))
11552 {
11553 return false;
11554 }
11555 break;
11556 }
11557
11558 // parse key
11559 if (JSON_HEDLEY_UNLIKELY(last_token != token_type::value_string))
11560 {
11561 return sax->parse_error(m_lexer.get_position(),
11562 m_lexer.get_token_string(),
11563 parse_error::create(101, m_lexer.get_position(), exception_message(token_type::value_string, "object key"), nullptr));
11564 }
11565 if (JSON_HEDLEY_UNLIKELY(!sax->key(m_lexer.get_string())))
11566 {
11567 return false;
11568 }
11569
11570 // parse separator (:)
11571 if (JSON_HEDLEY_UNLIKELY(get_token() != token_type::name_separator))
11572 {
11573 return sax->parse_error(m_lexer.get_position(),
11574 m_lexer.get_token_string(),
11575 parse_error::create(101, m_lexer.get_position(), exception_message(token_type::name_separator, "object separator"), nullptr));
11576 }
11577
11578 // remember we are now inside an object
11579 states.push_back(false);
11580
11581 // parse values
11582 get_token();
11583 continue;
11584 }
11585
11586 case token_type::begin_array:
11587 {
11588 if (JSON_HEDLEY_UNLIKELY(!sax->start_array(static_cast<std::size_t>(-1))))
11589 {
11590 return false;
11591 }
11592
11593 // closing ] -> we are done
11594 if (get_token() == token_type::end_array)
11595 {
11596 if (JSON_HEDLEY_UNLIKELY(!sax->end_array()))
11597 {
11598 return false;
11599 }
11600 break;
11601 }
11602
11603 // remember we are now inside an array
11604 states.push_back(true);
11605
11606 // parse values (no need to call get_token)
11607 continue;
11608 }
11609
11610 case token_type::value_float:
11611 {
11612 const auto res = m_lexer.get_number_float();
11613
11614 if (JSON_HEDLEY_UNLIKELY(!std::isfinite(res)))
11615 {
11616 return sax->parse_error(m_lexer.get_position(),
11617 m_lexer.get_token_string(),
11618 out_of_range::create(406, concat("number overflow parsing '", m_lexer.get_token_string(), '\''), nullptr));
11619 }
11620
11621 if (JSON_HEDLEY_UNLIKELY(!sax->number_float(res, m_lexer.get_string())))
11622 {
11623 return false;
11624 }
11625
11626 break;
11627 }
11628
11629 case token_type::literal_false:
11630 {
11631 if (JSON_HEDLEY_UNLIKELY(!sax->boolean(false)))
11632 {
11633 return false;
11634 }
11635 break;
11636 }
11637
11638 case token_type::literal_null:
11639 {
11640 if (JSON_HEDLEY_UNLIKELY(!sax->null()))
11641 {
11642 return false;
11643 }
11644 break;
11645 }
11646
11647 case token_type::literal_true:
11648 {
11649 if (JSON_HEDLEY_UNLIKELY(!sax->boolean(true)))
11650 {
11651 return false;
11652 }
11653 break;
11654 }
11655
11656 case token_type::value_integer:
11657 {
11658 if (JSON_HEDLEY_UNLIKELY(!sax->number_integer(m_lexer.get_number_integer())))
11659 {
11660 return false;
11661 }
11662 break;
11663 }
11664
11665 case token_type::value_string:
11666 {
11667 if (JSON_HEDLEY_UNLIKELY(!sax->string(m_lexer.get_string())))
11668 {
11669 return false;
11670 }
11671 break;
11672 }
11673
11674 case token_type::value_unsigned:
11675 {
11676 if (JSON_HEDLEY_UNLIKELY(!sax->number_unsigned(m_lexer.get_number_unsigned())))
11677 {
11678 return false;
11679 }
11680 break;
11681 }
11682
11683 case token_type::parse_error:
11684 {
11685 // using "uninitialized" to avoid "expected" message
11686 return sax->parse_error(m_lexer.get_position(),
11687 m_lexer.get_token_string(),
11688 parse_error::create(101, m_lexer.get_position(), exception_message(token_type::uninitialized, "value"), nullptr));
11689 }
11690
11691 case token_type::uninitialized:
11692 case token_type::end_array:
11693 case token_type::end_object:
11694 case token_type::name_separator:
11695 case token_type::value_separator:
11696 case token_type::end_of_input:
11697 case token_type::literal_or_value:
11698 default: // the last token was unexpected
11699 {
11700 return sax->parse_error(m_lexer.get_position(),
11701 m_lexer.get_token_string(),
11702 parse_error::create(101, m_lexer.get_position(), exception_message(token_type::literal_or_value, "value"), nullptr));
11703 }
11704 }
11705 }
11706 else
11707 {
11708 skip_to_state_evaluation = false;
11709 }
11710
11711 // we reached this line after we successfully parsed a value
11712 if (states.empty())
11713 {
11714 // empty stack: we reached the end of the hierarchy: done
11715 return true;
11716 }
11717
11718 if (states.back()) // array
11719 {
11720 // comma -> next value
11721 if (get_token() == token_type::value_separator)
11722 {
11723 // parse a new value
11724 get_token();
11725 continue;
11726 }
11727
11728 // closing ]
11729 if (JSON_HEDLEY_LIKELY(last_token == token_type::end_array))
11730 {
11731 if (JSON_HEDLEY_UNLIKELY(!sax->end_array()))
11732 {
11733 return false;
11734 }
11735
11736 // We are done with this array. Before we can parse a
11737 // new value, we need to evaluate the new state first.
11738 // By setting skip_to_state_evaluation to false, we
11739 // are effectively jumping to the beginning of this if.
11740 JSON_ASSERT(!states.empty());
11741 states.pop_back();
11742 skip_to_state_evaluation = true;
11743 continue;
11744 }
11745
11746 return sax->parse_error(m_lexer.get_position(),
11747 m_lexer.get_token_string(),
11748 parse_error::create(101, m_lexer.get_position(), exception_message(token_type::end_array, "array"), nullptr));
11749 }
11750
11751 // states.back() is false -> object
11752
11753 // comma -> next value
11754 if (get_token() == token_type::value_separator)
11755 {
11756 // parse key
11757 if (JSON_HEDLEY_UNLIKELY(get_token() != token_type::value_string))
11758 {
11759 return sax->parse_error(m_lexer.get_position(),
11760 m_lexer.get_token_string(),
11761 parse_error::create(101, m_lexer.get_position(), exception_message(token_type::value_string, "object key"), nullptr));
11762 }
11763
11764 if (JSON_HEDLEY_UNLIKELY(!sax->key(m_lexer.get_string())))
11765 {
11766 return false;
11767 }
11768
11769 // parse separator (:)
11770 if (JSON_HEDLEY_UNLIKELY(get_token() != token_type::name_separator))
11771 {
11772 return sax->parse_error(m_lexer.get_position(),
11773 m_lexer.get_token_string(),
11774 parse_error::create(101, m_lexer.get_position(), exception_message(token_type::name_separator, "object separator"), nullptr));
11775 }
11776
11777 // parse values
11778 get_token();
11779 continue;
11780 }
11781
11782 // closing }
11783 if (JSON_HEDLEY_LIKELY(last_token == token_type::end_object))
11784 {
11785 if (JSON_HEDLEY_UNLIKELY(!sax->end_object()))
11786 {
11787 return false;
11788 }
11789
11790 // We are done with this object. Before we can parse a
11791 // new value, we need to evaluate the new state first.
11792 // By setting skip_to_state_evaluation to false, we
11793 // are effectively jumping to the beginning of this if.
11794 JSON_ASSERT(!states.empty());
11795 states.pop_back();
11796 skip_to_state_evaluation = true;
11797 continue;
11798 }
11799
11800 return sax->parse_error(m_lexer.get_position(),
11801 m_lexer.get_token_string(),
11802 parse_error::create(101, m_lexer.get_position(), exception_message(token_type::end_object, "object"), nullptr));
11803 }
11804 }
11805
11807 token_type get_token()
11808 {
11809 return last_token = m_lexer.scan();
11810 }
11811
11812 std::string exception_message(const token_type expected, const std::string& context)
11813 {
11814 std::string error_msg = "syntax error ";
11815
11816 if (!context.empty())
11817 {
11818 error_msg += concat("while parsing ", context, ' ');
11819 }
11820
11821 error_msg += "- ";
11822
11823 if (last_token == token_type::parse_error)
11824 {
11825 error_msg += concat(m_lexer.get_error_message(), "; last read: '",
11826 m_lexer.get_token_string(), '\'');
11827 }
11828 else
11829 {
11830 error_msg += concat("unexpected ", lexer_t::token_type_name(last_token));
11831 }
11832
11833 if (expected != token_type::uninitialized)
11834 {
11835 error_msg += concat("; expected ", lexer_t::token_type_name(expected));
11836 }
11837
11838 return error_msg;
11839 }
11840
11841 private:
11843 const parser_callback_t<BasicJsonType> callback = nullptr;
11845 token_type last_token = token_type::uninitialized;
11847 lexer_t m_lexer;
11849 const bool allow_exceptions = true;
11850};
11851
11852} // namespace detail
11853} // namespace nlohmann
11854
11855// #include <nlohmann/detail/iterators/internal_iterator.hpp>
11856
11857
11858// #include <nlohmann/detail/iterators/primitive_iterator.hpp>
11859
11860
11861#include <cstddef> // ptrdiff_t
11862#include <limits> // numeric_limits
11863
11864// #include <nlohmann/detail/macro_scope.hpp>
11865
11866
11867namespace nlohmann
11868{
11869namespace detail
11870{
11871/*
11872@brief an iterator for primitive JSON types
11873
11874This class models an iterator for primitive JSON types (boolean, number,
11875string). It's only purpose is to allow the iterator/const_iterator classes
11876to "iterate" over primitive values. Internally, the iterator is modeled by
11877a `difference_type` variable. Value begin_value (`0`) models the begin,
11878end_value (`1`) models past the end.
11879*/
11880class primitive_iterator_t
11881{
11882 private:
11883 using difference_type = std::ptrdiff_t;
11884 static constexpr difference_type begin_value = 0;
11885 static constexpr difference_type end_value = begin_value + 1;
11886
11889 difference_type m_it = (std::numeric_limits<std::ptrdiff_t>::min)();
11890
11891 public:
11892 constexpr difference_type get_value() const noexcept
11893 {
11894 return m_it;
11895 }
11896
11898 void set_begin() noexcept
11899 {
11900 m_it = begin_value;
11901 }
11902
11904 void set_end() noexcept
11905 {
11906 m_it = end_value;
11907 }
11908
11910 constexpr bool is_begin() const noexcept
11911 {
11912 return m_it == begin_value;
11913 }
11914
11916 constexpr bool is_end() const noexcept
11917 {
11918 return m_it == end_value;
11919 }
11920
11921 friend constexpr bool operator==(primitive_iterator_t lhs, primitive_iterator_t rhs) noexcept
11922 {
11923 return lhs.m_it == rhs.m_it;
11924 }
11925
11926 friend constexpr bool operator<(primitive_iterator_t lhs, primitive_iterator_t rhs) noexcept
11927 {
11928 return lhs.m_it < rhs.m_it;
11929 }
11930
11931 primitive_iterator_t operator+(difference_type n) noexcept
11932 {
11933 auto result = *this;
11934 result += n;
11935 return result;
11936 }
11937
11938 friend constexpr difference_type operator-(primitive_iterator_t lhs, primitive_iterator_t rhs) noexcept
11939 {
11940 return lhs.m_it - rhs.m_it;
11941 }
11942
11943 primitive_iterator_t& operator++() noexcept
11944 {
11945 ++m_it;
11946 return *this;
11947 }
11948
11949 primitive_iterator_t operator++(int)& noexcept // NOLINT(cert-dcl21-cpp)
11950 {
11951 auto result = *this;
11952 ++m_it;
11953 return result;
11954 }
11955
11956 primitive_iterator_t& operator--() noexcept
11957 {
11958 --m_it;
11959 return *this;
11960 }
11961
11962 primitive_iterator_t operator--(int)& noexcept // NOLINT(cert-dcl21-cpp)
11963 {
11964 auto result = *this;
11965 --m_it;
11966 return result;
11967 }
11968
11969 primitive_iterator_t& operator+=(difference_type n) noexcept
11970 {
11971 m_it += n;
11972 return *this;
11973 }
11974
11975 primitive_iterator_t& operator-=(difference_type n) noexcept
11976 {
11977 m_it -= n;
11978 return *this;
11979 }
11980};
11981} // namespace detail
11982} // namespace nlohmann
11983
11984
11985namespace nlohmann
11986{
11987namespace detail
11988{
11995template<typename BasicJsonType> struct internal_iterator
11996{
11998 typename BasicJsonType::object_t::iterator object_iterator {};
12000 typename BasicJsonType::array_t::iterator array_iterator {};
12002 primitive_iterator_t primitive_iterator {};
12003};
12004} // namespace detail
12005} // namespace nlohmann
12006
12007// #include <nlohmann/detail/iterators/iter_impl.hpp>
12008
12009
12010#include <iterator> // iterator, random_access_iterator_tag, bidirectional_iterator_tag, advance, next
12011#include <type_traits> // conditional, is_const, remove_const
12012
12013// #include <nlohmann/detail/exceptions.hpp>
12014
12015// #include <nlohmann/detail/iterators/internal_iterator.hpp>
12016
12017// #include <nlohmann/detail/iterators/primitive_iterator.hpp>
12018
12019// #include <nlohmann/detail/macro_scope.hpp>
12020
12021// #include <nlohmann/detail/meta/cpp_future.hpp>
12022
12023// #include <nlohmann/detail/meta/type_traits.hpp>
12024
12025// #include <nlohmann/detail/value_t.hpp>
12026
12027
12028namespace nlohmann
12029{
12030namespace detail
12031{
12032// forward declare, to be able to friend it later on
12033template<typename IteratorType> class iteration_proxy;
12034template<typename IteratorType> class iteration_proxy_value;
12035
12052template<typename BasicJsonType>
12053class iter_impl // NOLINT(cppcoreguidelines-special-member-functions,hicpp-special-member-functions)
12054{
12056 using other_iter_impl = iter_impl<typename std::conditional<std::is_const<BasicJsonType>::value, typename std::remove_const<BasicJsonType>::type, const BasicJsonType>::type>;
12058 friend other_iter_impl;
12059 friend BasicJsonType;
12060 friend iteration_proxy<iter_impl>;
12061 friend iteration_proxy_value<iter_impl>;
12062
12063 using object_t = typename BasicJsonType::object_t;
12064 using array_t = typename BasicJsonType::array_t;
12065 // make sure BasicJsonType is basic_json or const basic_json
12067 "iter_impl only accepts (const) basic_json");
12068
12069 public:
12070
12076 using iterator_category = std::bidirectional_iterator_tag;
12077
12079 using value_type = typename BasicJsonType::value_type;
12081 using difference_type = typename BasicJsonType::difference_type;
12083 using pointer = typename std::conditional<std::is_const<BasicJsonType>::value,
12084 typename BasicJsonType::const_pointer,
12085 typename BasicJsonType::pointer>::type;
12088 typename std::conditional<std::is_const<BasicJsonType>::value,
12089 typename BasicJsonType::const_reference,
12090 typename BasicJsonType::reference>::type;
12091
12092 iter_impl() = default;
12093 ~iter_impl() = default;
12094 iter_impl(iter_impl&&) noexcept = default;
12095 iter_impl& operator=(iter_impl&&) noexcept = default;
12096
12103 explicit iter_impl(pointer object) noexcept : m_object(object)
12104 {
12105 JSON_ASSERT(m_object != nullptr);
12106
12107 switch (m_object->m_type)
12108 {
12109 case value_t::object:
12110 {
12111 m_it.object_iterator = typename object_t::iterator();
12112 break;
12113 }
12114
12115 case value_t::array:
12116 {
12117 m_it.array_iterator = typename array_t::iterator();
12118 break;
12119 }
12120
12121 case value_t::null:
12122 case value_t::string:
12123 case value_t::boolean:
12127 case value_t::binary:
12128 case value_t::discarded:
12129 default:
12130 {
12131 m_it.primitive_iterator = primitive_iterator_t();
12132 break;
12133 }
12134 }
12135 }
12136
12154 : m_object(other.m_object), m_it(other.m_it)
12155 {}
12156
12164 {
12165 if (&other != this)
12166 {
12167 m_object = other.m_object;
12168 m_it = other.m_it;
12169 }
12170 return *this;
12171 }
12172
12178 iter_impl(const iter_impl<typename std::remove_const<BasicJsonType>::type>& other) noexcept
12179 : m_object(other.m_object), m_it(other.m_it)
12180 {}
12181
12188 iter_impl& operator=(const iter_impl<typename std::remove_const<BasicJsonType>::type>& other) noexcept // NOLINT(cert-oop54-cpp)
12189 {
12190 m_object = other.m_object;
12191 m_it = other.m_it;
12192 return *this;
12193 }
12194
12200 void set_begin() noexcept
12201 {
12202 JSON_ASSERT(m_object != nullptr);
12203
12204 switch (m_object->m_type)
12205 {
12206 case value_t::object:
12207 {
12208 m_it.object_iterator = m_object->m_value.object->begin();
12209 break;
12210 }
12211
12212 case value_t::array:
12213 {
12214 m_it.array_iterator = m_object->m_value.array->begin();
12215 break;
12216 }
12217
12218 case value_t::null:
12219 {
12220 // set to end so begin()==end() is true: null is empty
12221 m_it.primitive_iterator.set_end();
12222 break;
12223 }
12224
12225 case value_t::string:
12226 case value_t::boolean:
12230 case value_t::binary:
12231 case value_t::discarded:
12232 default:
12233 {
12234 m_it.primitive_iterator.set_begin();
12235 break;
12236 }
12237 }
12238 }
12239
12244 void set_end() noexcept
12245 {
12246 JSON_ASSERT(m_object != nullptr);
12247
12248 switch (m_object->m_type)
12249 {
12250 case value_t::object:
12251 {
12252 m_it.object_iterator = m_object->m_value.object->end();
12253 break;
12254 }
12255
12256 case value_t::array:
12257 {
12258 m_it.array_iterator = m_object->m_value.array->end();
12259 break;
12260 }
12261
12262 case value_t::null:
12263 case value_t::string:
12264 case value_t::boolean:
12268 case value_t::binary:
12269 case value_t::discarded:
12270 default:
12271 {
12272 m_it.primitive_iterator.set_end();
12273 break;
12274 }
12275 }
12276 }
12277
12278 public:
12284 {
12285 JSON_ASSERT(m_object != nullptr);
12286
12287 switch (m_object->m_type)
12288 {
12289 case value_t::object:
12290 {
12291 JSON_ASSERT(m_it.object_iterator != m_object->m_value.object->end());
12292 return m_it.object_iterator->second;
12293 }
12294
12295 case value_t::array:
12296 {
12297 JSON_ASSERT(m_it.array_iterator != m_object->m_value.array->end());
12298 return *m_it.array_iterator;
12299 }
12300
12301 case value_t::null:
12302 JSON_THROW(invalid_iterator::create(214, "cannot get value", m_object));
12303
12304 case value_t::string:
12305 case value_t::boolean:
12309 case value_t::binary:
12310 case value_t::discarded:
12311 default:
12312 {
12314 {
12315 return *m_object;
12316 }
12317
12318 JSON_THROW(invalid_iterator::create(214, "cannot get value", m_object));
12319 }
12320 }
12321 }
12322
12328 {
12329 JSON_ASSERT(m_object != nullptr);
12330
12331 switch (m_object->m_type)
12332 {
12333 case value_t::object:
12334 {
12335 JSON_ASSERT(m_it.object_iterator != m_object->m_value.object->end());
12336 return &(m_it.object_iterator->second);
12337 }
12338
12339 case value_t::array:
12340 {
12341 JSON_ASSERT(m_it.array_iterator != m_object->m_value.array->end());
12342 return &*m_it.array_iterator;
12343 }
12344
12345 case value_t::null:
12346 case value_t::string:
12347 case value_t::boolean:
12351 case value_t::binary:
12352 case value_t::discarded:
12353 default:
12354 {
12356 {
12357 return m_object;
12358 }
12359
12360 JSON_THROW(invalid_iterator::create(214, "cannot get value", m_object));
12361 }
12362 }
12363 }
12364
12369 iter_impl operator++(int)& // NOLINT(cert-dcl21-cpp)
12370 {
12371 auto result = *this;
12372 ++(*this);
12373 return result;
12374 }
12375
12381 {
12382 JSON_ASSERT(m_object != nullptr);
12383
12384 switch (m_object->m_type)
12385 {
12386 case value_t::object:
12387 {
12388 std::advance(m_it.object_iterator, 1);
12389 break;
12390 }
12391
12392 case value_t::array:
12393 {
12394 std::advance(m_it.array_iterator, 1);
12395 break;
12396 }
12397
12398 case value_t::null:
12399 case value_t::string:
12400 case value_t::boolean:
12404 case value_t::binary:
12405 case value_t::discarded:
12406 default:
12407 {
12409 break;
12410 }
12411 }
12412
12413 return *this;
12414 }
12415
12420 iter_impl operator--(int)& // NOLINT(cert-dcl21-cpp)
12421 {
12422 auto result = *this;
12423 --(*this);
12424 return result;
12425 }
12426
12432 {
12433 JSON_ASSERT(m_object != nullptr);
12434
12435 switch (m_object->m_type)
12436 {
12437 case value_t::object:
12438 {
12439 std::advance(m_it.object_iterator, -1);
12440 break;
12441 }
12442
12443 case value_t::array:
12444 {
12445 std::advance(m_it.array_iterator, -1);
12446 break;
12447 }
12448
12449 case value_t::null:
12450 case value_t::string:
12451 case value_t::boolean:
12455 case value_t::binary:
12456 case value_t::discarded:
12457 default:
12458 {
12460 break;
12461 }
12462 }
12463
12464 return *this;
12465 }
12466
12471 template < typename IterImpl, detail::enable_if_t < (std::is_same<IterImpl, iter_impl>::value || std::is_same<IterImpl, other_iter_impl>::value), std::nullptr_t > = nullptr >
12472 bool operator==(const IterImpl& other) const
12473 {
12474 // if objects are not the same, the comparison is undefined
12475 if (JSON_HEDLEY_UNLIKELY(m_object != other.m_object))
12476 {
12477 JSON_THROW(invalid_iterator::create(212, "cannot compare iterators of different containers", m_object));
12478 }
12479
12480 JSON_ASSERT(m_object != nullptr);
12481
12482 switch (m_object->m_type)
12483 {
12484 case value_t::object:
12485 return (m_it.object_iterator == other.m_it.object_iterator);
12486
12487 case value_t::array:
12488 return (m_it.array_iterator == other.m_it.array_iterator);
12489
12490 case value_t::null:
12491 case value_t::string:
12492 case value_t::boolean:
12496 case value_t::binary:
12497 case value_t::discarded:
12498 default:
12499 return (m_it.primitive_iterator == other.m_it.primitive_iterator);
12500 }
12501 }
12502
12507 template < typename IterImpl, detail::enable_if_t < (std::is_same<IterImpl, iter_impl>::value || std::is_same<IterImpl, other_iter_impl>::value), std::nullptr_t > = nullptr >
12508 bool operator!=(const IterImpl& other) const
12509 {
12510 return !operator==(other);
12511 }
12512
12517 bool operator<(const iter_impl& other) const
12518 {
12519 // if objects are not the same, the comparison is undefined
12520 if (JSON_HEDLEY_UNLIKELY(m_object != other.m_object))
12521 {
12522 JSON_THROW(invalid_iterator::create(212, "cannot compare iterators of different containers", m_object));
12523 }
12524
12525 JSON_ASSERT(m_object != nullptr);
12526
12527 switch (m_object->m_type)
12528 {
12529 case value_t::object:
12530 JSON_THROW(invalid_iterator::create(213, "cannot compare order of object iterators", m_object));
12531
12532 case value_t::array:
12533 return (m_it.array_iterator < other.m_it.array_iterator);
12534
12535 case value_t::null:
12536 case value_t::string:
12537 case value_t::boolean:
12541 case value_t::binary:
12542 case value_t::discarded:
12543 default:
12545 }
12546 }
12547
12552 bool operator<=(const iter_impl& other) const
12553 {
12554 return !other.operator < (*this);
12555 }
12556
12561 bool operator>(const iter_impl& other) const
12562 {
12563 return !operator<=(other);
12564 }
12565
12570 bool operator>=(const iter_impl& other) const
12571 {
12572 return !operator<(other);
12573 }
12574
12580 {
12581 JSON_ASSERT(m_object != nullptr);
12582
12583 switch (m_object->m_type)
12584 {
12585 case value_t::object:
12586 JSON_THROW(invalid_iterator::create(209, "cannot use offsets with object iterators", m_object));
12587
12588 case value_t::array:
12589 {
12590 std::advance(m_it.array_iterator, i);
12591 break;
12592 }
12593
12594 case value_t::null:
12595 case value_t::string:
12596 case value_t::boolean:
12600 case value_t::binary:
12601 case value_t::discarded:
12602 default:
12603 {
12605 break;
12606 }
12607 }
12608
12609 return *this;
12610 }
12611
12617 {
12618 return operator+=(-i);
12619 }
12620
12626 {
12627 auto result = *this;
12628 result += i;
12629 return result;
12630 }
12631
12637 {
12638 auto result = it;
12639 result += i;
12640 return result;
12641 }
12642
12648 {
12649 auto result = *this;
12650 result -= i;
12651 return result;
12652 }
12653
12659 {
12660 JSON_ASSERT(m_object != nullptr);
12661
12662 switch (m_object->m_type)
12663 {
12664 case value_t::object:
12665 JSON_THROW(invalid_iterator::create(209, "cannot use offsets with object iterators", m_object));
12666
12667 case value_t::array:
12668 return m_it.array_iterator - other.m_it.array_iterator;
12669
12670 case value_t::null:
12671 case value_t::string:
12672 case value_t::boolean:
12676 case value_t::binary:
12677 case value_t::discarded:
12678 default:
12680 }
12681 }
12682
12688 {
12689 JSON_ASSERT(m_object != nullptr);
12690
12691 switch (m_object->m_type)
12692 {
12693 case value_t::object:
12694 JSON_THROW(invalid_iterator::create(208, "cannot use operator[] for object iterators", m_object));
12695
12696 case value_t::array:
12697 return *std::next(m_it.array_iterator, n);
12698
12699 case value_t::null:
12700 JSON_THROW(invalid_iterator::create(214, "cannot get value", m_object));
12701
12702 case value_t::string:
12703 case value_t::boolean:
12707 case value_t::binary:
12708 case value_t::discarded:
12709 default:
12710 {
12711 if (JSON_HEDLEY_LIKELY(m_it.primitive_iterator.get_value() == -n))
12712 {
12713 return *m_object;
12714 }
12715
12716 JSON_THROW(invalid_iterator::create(214, "cannot get value", m_object));
12717 }
12718 }
12719 }
12720
12725 const typename object_t::key_type& key() const
12726 {
12727 JSON_ASSERT(m_object != nullptr);
12728
12729 if (JSON_HEDLEY_LIKELY(m_object->is_object()))
12730 {
12731 return m_it.object_iterator->first;
12732 }
12733
12734 JSON_THROW(invalid_iterator::create(207, "cannot use key() for non-object iterators", m_object));
12735 }
12736
12742 {
12743 return operator*();
12744 }
12745
12748 pointer m_object = nullptr;
12751};
12752} // namespace detail
12753} // namespace nlohmann
12754
12755// #include <nlohmann/detail/iterators/iteration_proxy.hpp>
12756
12757// #include <nlohmann/detail/iterators/json_reverse_iterator.hpp>
12758
12759
12760#include <cstddef> // ptrdiff_t
12761#include <iterator> // reverse_iterator
12762#include <utility> // declval
12763
12764namespace nlohmann
12765{
12766namespace detail
12767{
12769// reverse_iterator //
12771
12790template<typename Base>
12791class json_reverse_iterator : public std::reverse_iterator<Base>
12792{
12793 public:
12794 using difference_type = std::ptrdiff_t;
12796 using base_iterator = std::reverse_iterator<Base>;
12798 using reference = typename Base::reference;
12799
12801 explicit json_reverse_iterator(const typename base_iterator::iterator_type& it) noexcept
12802 : base_iterator(it) {}
12803
12805 explicit json_reverse_iterator(const base_iterator& it) noexcept : base_iterator(it) {}
12806
12808 json_reverse_iterator operator++(int)& // NOLINT(cert-dcl21-cpp)
12809 {
12810 return static_cast<json_reverse_iterator>(base_iterator::operator++(1));
12811 }
12812
12815 {
12816 return static_cast<json_reverse_iterator&>(base_iterator::operator++());
12817 }
12818
12820 json_reverse_iterator operator--(int)& // NOLINT(cert-dcl21-cpp)
12821 {
12822 return static_cast<json_reverse_iterator>(base_iterator::operator--(1));
12823 }
12824
12827 {
12828 return static_cast<json_reverse_iterator&>(base_iterator::operator--());
12829 }
12830
12833 {
12834 return static_cast<json_reverse_iterator&>(base_iterator::operator+=(i));
12835 }
12836
12839 {
12840 return static_cast<json_reverse_iterator>(base_iterator::operator+(i));
12841 }
12842
12845 {
12846 return static_cast<json_reverse_iterator>(base_iterator::operator-(i));
12847 }
12848
12851 {
12852 return base_iterator(*this) - base_iterator(other);
12853 }
12854
12857 {
12858 return *(this->operator+(n));
12859 }
12860
12862 auto key() const -> decltype(std::declval<Base>().key())
12863 {
12864 auto it = --this->base();
12865 return it.key();
12866 }
12867
12870 {
12871 auto it = --this->base();
12872 return it.operator * ();
12873 }
12874};
12875} // namespace detail
12876} // namespace nlohmann
12877
12878// #include <nlohmann/detail/iterators/primitive_iterator.hpp>
12879
12880// #include <nlohmann/detail/json_pointer.hpp>
12881
12882
12883#include <algorithm> // all_of
12884#include <cctype> // isdigit
12885#include <cerrno> // errno, ERANGE
12886#include <cstdlib> // strtoull
12887#include <limits> // max
12888#include <numeric> // accumulate
12889#include <string> // string
12890#include <utility> // move
12891#include <vector> // vector
12892
12893// #include <nlohmann/detail/exceptions.hpp>
12894
12895// #include <nlohmann/detail/macro_scope.hpp>
12896
12897// #include <nlohmann/detail/string_concat.hpp>
12898
12899// #include <nlohmann/detail/string_escape.hpp>
12900
12901// #include <nlohmann/detail/value_t.hpp>
12902
12903
12904namespace nlohmann
12905{
12906
12909template<typename RefStringType>
12911{
12912 // allow basic_json to access private members
12914 friend class basic_json;
12915
12916 template<typename>
12917 friend class json_pointer;
12918
12919 template<typename T>
12920 struct string_t_helper
12921 {
12922 using type = T;
12923 };
12924
12926 struct string_t_helper<NLOHMANN_BASIC_JSON_TPL>
12927 {
12928 using type = StringType;
12929 };
12930
12931 public:
12932 // for backwards compatibility accept BasicJsonType
12933 using string_t = typename string_t_helper<RefStringType>::type;
12934
12937 explicit json_pointer(const string_t& s = "")
12938 : reference_tokens(split(s))
12939 {}
12940
12944 {
12945 return std::accumulate(reference_tokens.begin(), reference_tokens.end(),
12946 string_t{},
12947 [](const string_t& a, const string_t& b)
12948 {
12949 return detail::concat(a, '/', detail::escape(b));
12950 });
12951 }
12952
12955 operator string_t() const
12956 {
12957 return to_string();
12958 }
12959
12963 {
12964 reference_tokens.insert(reference_tokens.end(),
12965 ptr.reference_tokens.begin(),
12966 ptr.reference_tokens.end());
12967 return *this;
12968 }
12969
12973 {
12974 push_back(std::move(token));
12975 return *this;
12976 }
12977
12980 json_pointer& operator/=(std::size_t array_idx)
12981 {
12982 return *this /= std::to_string(array_idx);
12983 }
12984
12988 const json_pointer& rhs)
12989 {
12990 return json_pointer(lhs) /= rhs;
12991 }
12992
12995 friend json_pointer operator/(const json_pointer& lhs, string_t token) // NOLINT(performance-unnecessary-value-param)
12996 {
12997 return json_pointer(lhs) /= std::move(token);
12998 }
12999
13002 friend json_pointer operator/(const json_pointer& lhs, std::size_t array_idx)
13003 {
13004 return json_pointer(lhs) /= array_idx;
13005 }
13006
13010 {
13011 if (empty())
13012 {
13013 return *this;
13014 }
13015
13016 json_pointer res = *this;
13017 res.pop_back();
13018 return res;
13019 }
13020
13024 {
13026 {
13027 JSON_THROW(detail::out_of_range::create(405, "JSON pointer has no parent", nullptr));
13028 }
13029
13030 reference_tokens.pop_back();
13031 }
13032
13035 const string_t& back() const
13036 {
13038 {
13039 JSON_THROW(detail::out_of_range::create(405, "JSON pointer has no parent", nullptr));
13040 }
13041
13042 return reference_tokens.back();
13043 }
13044
13047 void push_back(const string_t& token)
13048 {
13049 reference_tokens.push_back(token);
13050 }
13051
13054 void push_back(string_t&& token)
13055 {
13056 reference_tokens.push_back(std::move(token));
13057 }
13058
13061 bool empty() const noexcept
13062 {
13063 return reference_tokens.empty();
13064 }
13065
13066 private:
13077 template<typename BasicJsonType>
13078 static typename BasicJsonType::size_type array_index(const string_t& s)
13079 {
13080 using size_type = typename BasicJsonType::size_type;
13081
13082 // error condition (cf. RFC 6901, Sect. 4)
13083 if (JSON_HEDLEY_UNLIKELY(s.size() > 1 && s[0] == '0'))
13084 {
13085 JSON_THROW(detail::parse_error::create(106, 0, detail::concat("array index '", s, "' must not begin with '0'"), nullptr));
13086 }
13087
13088 // error condition (cf. RFC 6901, Sect. 4)
13089 if (JSON_HEDLEY_UNLIKELY(s.size() > 1 && !(s[0] >= '1' && s[0] <= '9')))
13090 {
13091 JSON_THROW(detail::parse_error::create(109, 0, detail::concat("array index '", s, "' is not a number"), nullptr));
13092 }
13093
13094 const char* p = s.c_str();
13095 char* p_end = nullptr;
13096 errno = 0; // strtoull doesn't reset errno
13097 unsigned long long res = std::strtoull(p, &p_end, 10); // NOLINT(runtime/int)
13098 if (p == p_end // invalid input or empty string
13099 || errno == ERANGE // out of range
13100 || JSON_HEDLEY_UNLIKELY(static_cast<std::size_t>(p_end - p) != s.size())) // incomplete read
13101 {
13102 JSON_THROW(detail::out_of_range::create(404, detail::concat("unresolved reference token '", s, "'"), nullptr));
13103 }
13104
13105 // only triggered on special platforms (like 32bit), see also
13106 // https://github.com/nlohmann/json/pull/2203
13107 if (res >= static_cast<unsigned long long>((std::numeric_limits<size_type>::max)())) // NOLINT(runtime/int)
13108 {
13109 JSON_THROW(detail::out_of_range::create(410, detail::concat("array index ", s, " exceeds size_type"), nullptr)); // LCOV_EXCL_LINE
13110 }
13111
13112 return static_cast<size_type>(res);
13113 }
13114
13116 json_pointer top() const
13117 {
13119 {
13120 JSON_THROW(detail::out_of_range::create(405, "JSON pointer has no parent", nullptr));
13121 }
13122
13123 json_pointer result = *this;
13124 result.reference_tokens = {reference_tokens[0]};
13125 return result;
13126 }
13127
13128 private:
13137 template<typename BasicJsonType>
13138 BasicJsonType& get_and_create(BasicJsonType& j) const
13139 {
13140 auto* result = &j;
13141
13142 // in case no reference tokens exist, return a reference to the JSON value
13143 // j which will be overwritten by a primitive value
13144 for (const auto& reference_token : reference_tokens)
13145 {
13146 switch (result->type())
13147 {
13149 {
13150 if (reference_token == "0")
13151 {
13152 // start a new array if reference token is 0
13153 result = &result->operator[](0);
13154 }
13155 else
13156 {
13157 // start a new object otherwise
13158 result = &result->operator[](reference_token);
13159 }
13160 break;
13161 }
13162
13164 {
13165 // create an entry in the object
13166 result = &result->operator[](reference_token);
13167 break;
13168 }
13169
13171 {
13172 // create an entry in the array
13173 result = &result->operator[](array_index<BasicJsonType>(reference_token));
13174 break;
13175 }
13176
13177 /*
13178 The following code is only reached if there exists a reference
13179 token _and_ the current value is primitive. In this case, we have
13180 an error situation, because primitive values may only occur as
13181 single value; that is, with an empty list of reference tokens.
13182 */
13190 default:
13191 JSON_THROW(detail::type_error::create(313, "invalid value to unflatten", &j));
13192 }
13193 }
13194
13195 return *result;
13196 }
13197
13217 template<typename BasicJsonType>
13218 BasicJsonType& get_unchecked(BasicJsonType* ptr) const
13219 {
13220 for (const auto& reference_token : reference_tokens)
13221 {
13222 // convert null values to arrays or objects before continuing
13223 if (ptr->is_null())
13224 {
13225 // check if reference token is a number
13226 const bool nums =
13227 std::all_of(reference_token.begin(), reference_token.end(),
13228 [](const unsigned char x)
13229 {
13230 return std::isdigit(x);
13231 });
13232
13233 // change value to array for numbers or "-" or to object otherwise
13234 *ptr = (nums || reference_token == "-")
13236 : detail::value_t::object;
13237 }
13238
13239 switch (ptr->type())
13240 {
13242 {
13243 // use unchecked object access
13244 ptr = &ptr->operator[](reference_token);
13245 break;
13246 }
13247
13249 {
13250 if (reference_token == "-")
13251 {
13252 // explicitly treat "-" as index beyond the end
13253 ptr = &ptr->operator[](ptr->m_value.array->size());
13254 }
13255 else
13256 {
13257 // convert array index to number; unchecked access
13258 ptr = &ptr->operator[](array_index<BasicJsonType>(reference_token));
13259 }
13260 break;
13261 }
13262
13271 default:
13272 JSON_THROW(detail::out_of_range::create(404, detail::concat("unresolved reference token '", reference_token, "'"), ptr));
13273 }
13274 }
13275
13276 return *ptr;
13277 }
13278
13285 template<typename BasicJsonType>
13286 BasicJsonType& get_checked(BasicJsonType* ptr) const
13287 {
13288 for (const auto& reference_token : reference_tokens)
13289 {
13290 switch (ptr->type())
13291 {
13293 {
13294 // note: at performs range check
13295 ptr = &ptr->at(reference_token);
13296 break;
13297 }
13298
13300 {
13301 if (JSON_HEDLEY_UNLIKELY(reference_token == "-"))
13302 {
13303 // "-" always fails the range check
13305 "array index '-' (", std::to_string(ptr->m_value.array->size()),
13306 ") is out of range"), ptr));
13307 }
13308
13309 // note: at performs range check
13310 ptr = &ptr->at(array_index<BasicJsonType>(reference_token));
13311 break;
13312 }
13313
13322 default:
13323 JSON_THROW(detail::out_of_range::create(404, detail::concat("unresolved reference token '", reference_token, "'"), ptr));
13324 }
13325 }
13326
13327 return *ptr;
13328 }
13329
13343 template<typename BasicJsonType>
13344 const BasicJsonType& get_unchecked(const BasicJsonType* ptr) const
13345 {
13346 for (const auto& reference_token : reference_tokens)
13347 {
13348 switch (ptr->type())
13349 {
13351 {
13352 // use unchecked object access
13353 ptr = &ptr->operator[](reference_token);
13354 break;
13355 }
13356
13358 {
13359 if (JSON_HEDLEY_UNLIKELY(reference_token == "-"))
13360 {
13361 // "-" cannot be used for const access
13362 JSON_THROW(detail::out_of_range::create(402, detail::concat("array index '-' (", std::to_string(ptr->m_value.array->size()), ") is out of range"), ptr));
13363 }
13364
13365 // use unchecked array access
13366 ptr = &ptr->operator[](array_index<BasicJsonType>(reference_token));
13367 break;
13368 }
13369
13378 default:
13379 JSON_THROW(detail::out_of_range::create(404, detail::concat("unresolved reference token '", reference_token, "'"), ptr));
13380 }
13381 }
13382
13383 return *ptr;
13384 }
13385
13392 template<typename BasicJsonType>
13393 const BasicJsonType& get_checked(const BasicJsonType* ptr) const
13394 {
13395 for (const auto& reference_token : reference_tokens)
13396 {
13397 switch (ptr->type())
13398 {
13400 {
13401 // note: at performs range check
13402 ptr = &ptr->at(reference_token);
13403 break;
13404 }
13405
13407 {
13408 if (JSON_HEDLEY_UNLIKELY(reference_token == "-"))
13409 {
13410 // "-" always fails the range check
13412 "array index '-' (", std::to_string(ptr->m_value.array->size()),
13413 ") is out of range"), ptr));
13414 }
13415
13416 // note: at performs range check
13417 ptr = &ptr->at(array_index<BasicJsonType>(reference_token));
13418 break;
13419 }
13420
13429 default:
13430 JSON_THROW(detail::out_of_range::create(404, detail::concat("unresolved reference token '", reference_token, "'"), ptr));
13431 }
13432 }
13433
13434 return *ptr;
13435 }
13436
13441 template<typename BasicJsonType>
13442 bool contains(const BasicJsonType* ptr) const
13443 {
13444 for (const auto& reference_token : reference_tokens)
13445 {
13446 switch (ptr->type())
13447 {
13449 {
13450 if (!ptr->contains(reference_token))
13451 {
13452 // we did not find the key in the object
13453 return false;
13454 }
13455
13456 ptr = &ptr->operator[](reference_token);
13457 break;
13458 }
13459
13461 {
13462 if (JSON_HEDLEY_UNLIKELY(reference_token == "-"))
13463 {
13464 // "-" always fails the range check
13465 return false;
13466 }
13467 if (JSON_HEDLEY_UNLIKELY(reference_token.size() == 1 && !("0" <= reference_token && reference_token <= "9")))
13468 {
13469 // invalid char
13470 return false;
13471 }
13472 if (JSON_HEDLEY_UNLIKELY(reference_token.size() > 1))
13473 {
13474 if (JSON_HEDLEY_UNLIKELY(!('1' <= reference_token[0] && reference_token[0] <= '9')))
13475 {
13476 // first char should be between '1' and '9'
13477 return false;
13478 }
13479 for (std::size_t i = 1; i < reference_token.size(); i++)
13480 {
13481 if (JSON_HEDLEY_UNLIKELY(!('0' <= reference_token[i] && reference_token[i] <= '9')))
13482 {
13483 // other char should be between '0' and '9'
13484 return false;
13485 }
13486 }
13487 }
13488
13489 const auto idx = array_index<BasicJsonType>(reference_token);
13490 if (idx >= ptr->size())
13491 {
13492 // index out of range
13493 return false;
13494 }
13495
13496 ptr = &ptr->operator[](idx);
13497 break;
13498 }
13499
13508 default:
13509 {
13510 // we do not expect primitive values if there is still a
13511 // reference token to process
13512 return false;
13513 }
13514 }
13515 }
13516
13517 // no reference token left means we found a primitive value
13518 return true;
13519 }
13520
13530 static std::vector<string_t> split(const string_t& reference_string)
13531 {
13532 std::vector<string_t> result;
13533
13534 // special case: empty reference string -> no reference tokens
13535 if (reference_string.empty())
13536 {
13537 return result;
13538 }
13539
13540 // check if nonempty reference string begins with slash
13541 if (JSON_HEDLEY_UNLIKELY(reference_string[0] != '/'))
13542 {
13543 JSON_THROW(detail::parse_error::create(107, 1, detail::concat("JSON pointer must be empty or begin with '/' - was: '", reference_string, "'"), nullptr));
13544 }
13545
13546 // extract the reference tokens:
13547 // - slash: position of the last read slash (or end of string)
13548 // - start: position after the previous slash
13549 for (
13550 // search for the first slash after the first character
13551 std::size_t slash = reference_string.find_first_of('/', 1),
13552 // set the beginning of the first reference token
13553 start = 1;
13554 // we can stop if start == 0 (if slash == string_t::npos)
13555 start != 0;
13556 // set the beginning of the next reference token
13557 // (will eventually be 0 if slash == string_t::npos)
13558 start = (slash == string_t::npos) ? 0 : slash + 1,
13559 // find next slash
13560 slash = reference_string.find_first_of('/', start))
13561 {
13562 // use the text between the beginning of the reference token
13563 // (start) and the last slash (slash).
13564 auto reference_token = reference_string.substr(start, slash - start);
13565
13566 // check reference tokens are properly escaped
13567 for (std::size_t pos = reference_token.find_first_of('~');
13568 pos != string_t::npos;
13569 pos = reference_token.find_first_of('~', pos + 1))
13570 {
13571 JSON_ASSERT(reference_token[pos] == '~');
13572
13573 // ~ must be followed by 0 or 1
13574 if (JSON_HEDLEY_UNLIKELY(pos == reference_token.size() - 1 ||
13575 (reference_token[pos + 1] != '0' &&
13576 reference_token[pos + 1] != '1')))
13577 {
13578 JSON_THROW(detail::parse_error::create(108, 0, "escape character '~' must be followed with '0' or '1'", nullptr));
13579 }
13580 }
13581
13582 // finally, store the reference token
13583 detail::unescape(reference_token);
13584 result.push_back(reference_token);
13585 }
13586
13587 return result;
13588 }
13589
13590 private:
13598 template<typename BasicJsonType>
13599 static void flatten(const string_t& reference_string,
13600 const BasicJsonType& value,
13601 BasicJsonType& result)
13602 {
13603 switch (value.type())
13604 {
13606 {
13607 if (value.m_value.array->empty())
13608 {
13609 // flatten empty array as null
13610 result[reference_string] = nullptr;
13611 }
13612 else
13613 {
13614 // iterate array and use index as reference string
13615 for (std::size_t i = 0; i < value.m_value.array->size(); ++i)
13616 {
13617 flatten(detail::concat(reference_string, '/', std::to_string(i)),
13618 value.m_value.array->operator[](i), result);
13619 }
13620 }
13621 break;
13622 }
13623
13625 {
13626 if (value.m_value.object->empty())
13627 {
13628 // flatten empty object as null
13629 result[reference_string] = nullptr;
13630 }
13631 else
13632 {
13633 // iterate object and use keys as reference string
13634 for (const auto& element : *value.m_value.object)
13635 {
13636 flatten(detail::concat(reference_string, '/', detail::escape(element.first)), element.second, result);
13637 }
13638 }
13639 break;
13640 }
13641
13650 default:
13651 {
13652 // add primitive value with its reference string
13653 result[reference_string] = value;
13654 break;
13655 }
13656 }
13657 }
13658
13669 template<typename BasicJsonType>
13670 static BasicJsonType
13671 unflatten(const BasicJsonType& value)
13672 {
13673 if (JSON_HEDLEY_UNLIKELY(!value.is_object()))
13674 {
13675 JSON_THROW(detail::type_error::create(314, "only objects can be unflattened", &value));
13676 }
13677
13678 BasicJsonType result;
13679
13680 // iterate the JSON object values
13681 for (const auto& element : *value.m_value.object)
13682 {
13683 if (JSON_HEDLEY_UNLIKELY(!element.second.is_primitive()))
13684 {
13685 JSON_THROW(detail::type_error::create(315, "values in object must be primitive", &element.second));
13686 }
13687
13688 // assign value to reference pointed to by JSON pointer; Note that if
13689 // the JSON pointer is "" (i.e., points to the whole value), function
13690 // get_and_create returns a reference to result itself. An assignment
13691 // will then create a primitive value.
13692 json_pointer(element.first).get_and_create(result) = element.second;
13693 }
13694
13695 return result;
13696 }
13697
13698 // can't use conversion operator because of ambiguity
13699 json_pointer<string_t> convert() const&
13700 {
13701 json_pointer<string_t> result;
13702 result.reference_tokens = reference_tokens;
13703 return result;
13704 }
13705
13706 json_pointer<string_t> convert()&&
13707 {
13708 json_pointer<string_t> result;
13709 result.reference_tokens = std::move(reference_tokens);
13710 return result;
13711 }
13712
13724 template<typename RefStringTypeLhs, typename RefStringTypeRhs>
13725 // NOLINTNEXTLINE(readability-redundant-declaration)
13726 friend bool operator==(json_pointer<RefStringTypeLhs> const& lhs,
13727 json_pointer<RefStringTypeRhs> const& rhs) noexcept;
13728
13740 template<typename RefStringTypeLhs, typename RefStringTypeRhs>
13741 // NOLINTNEXTLINE(readability-redundant-declaration)
13742 friend bool operator!=(json_pointer<RefStringTypeLhs> const& lhs,
13743 json_pointer<RefStringTypeRhs> const& rhs) noexcept;
13744
13746 std::vector<string_t> reference_tokens;
13747};
13748
13749// functions cannot be defined inside class due to ODR violations
13750template<typename RefStringTypeLhs, typename RefStringTypeRhs>
13752 json_pointer<RefStringTypeRhs> const& rhs) noexcept
13753{
13754 return lhs.reference_tokens == rhs.reference_tokens;
13755}
13756
13757template<typename RefStringTypeLhs, typename RefStringTypeRhs>
13759 json_pointer<RefStringTypeRhs> const& rhs) noexcept
13760{
13761 return !(lhs == rhs);
13762}
13763} // namespace nlohmann
13764
13765// #include <nlohmann/detail/json_ref.hpp>
13766
13767
13768#include <initializer_list>
13769#include <utility>
13770
13771// #include <nlohmann/detail/meta/type_traits.hpp>
13772
13773
13774namespace nlohmann
13775{
13776namespace detail
13777{
13778template<typename BasicJsonType>
13780{
13781 public:
13782 using value_type = BasicJsonType;
13783
13785 : owned_value(std::move(value))
13786 {}
13787
13789 : value_ref(&value)
13790 {}
13791
13792 json_ref(std::initializer_list<json_ref> init)
13793 : owned_value(init)
13794 {}
13795
13796 template <
13797 class... Args,
13798 enable_if_t<std::is_constructible<value_type, Args...>::value, int> = 0 >
13799 json_ref(Args && ... args)
13800 : owned_value(std::forward<Args>(args)...)
13801 {}
13802
13803 // class should be movable only
13804 json_ref(json_ref&&) noexcept = default;
13805 json_ref(const json_ref&) = delete;
13806 json_ref& operator=(const json_ref&) = delete;
13807 json_ref& operator=(json_ref&&) = delete;
13808 ~json_ref() = default;
13809
13811 {
13812 if (value_ref == nullptr)
13813 {
13814 return std::move(owned_value);
13815 }
13816 return *value_ref;
13817 }
13818
13819 value_type const& operator*() const
13820 {
13821 return value_ref ? *value_ref : owned_value;
13822 }
13823
13824 value_type const* operator->() const
13825 {
13826 return &** this;
13827 }
13828
13829 private:
13830 mutable value_type owned_value = nullptr;
13831 value_type const* value_ref = nullptr;
13832};
13833} // namespace detail
13834} // namespace nlohmann
13835
13836// #include <nlohmann/detail/macro_scope.hpp>
13837
13838// #include <nlohmann/detail/string_concat.hpp>
13839
13840// #include <nlohmann/detail/string_escape.hpp>
13841
13842// #include <nlohmann/detail/meta/cpp_future.hpp>
13843
13844// #include <nlohmann/detail/meta/type_traits.hpp>
13845
13846// #include <nlohmann/detail/output/binary_writer.hpp>
13847
13848
13849#include <algorithm> // reverse
13850#include <array> // array
13851#include <map> // map
13852#include <cmath> // isnan, isinf
13853#include <cstdint> // uint8_t, uint16_t, uint32_t, uint64_t
13854#include <cstring> // memcpy
13855#include <limits> // numeric_limits
13856#include <string> // string
13857#include <utility> // move
13858#include <vector> // vector
13859
13860// #include <nlohmann/detail/input/binary_reader.hpp>
13861
13862// #include <nlohmann/detail/macro_scope.hpp>
13863
13864// #include <nlohmann/detail/output/output_adapters.hpp>
13865
13866
13867#include <algorithm> // copy
13868#include <cstddef> // size_t
13869#include <iterator> // back_inserter
13870#include <memory> // shared_ptr, make_shared
13871#include <string> // basic_string
13872#include <vector> // vector
13873
13874#ifndef JSON_NO_IO
13875 #include <ios> // streamsize
13876 #include <ostream> // basic_ostream
13877#endif // JSON_NO_IO
13878
13879// #include <nlohmann/detail/macro_scope.hpp>
13880
13881
13882namespace nlohmann
13883{
13884namespace detail
13885{
13887template<typename CharType> struct output_adapter_protocol
13888{
13889 virtual void write_character(CharType c) = 0;
13890 virtual void write_characters(const CharType* s, std::size_t length) = 0;
13891 virtual ~output_adapter_protocol() = default;
13892
13893 output_adapter_protocol() = default;
13894 output_adapter_protocol(const output_adapter_protocol&) = default;
13895 output_adapter_protocol(output_adapter_protocol&&) noexcept = default;
13896 output_adapter_protocol& operator=(const output_adapter_protocol&) = default;
13897 output_adapter_protocol& operator=(output_adapter_protocol&&) noexcept = default;
13898};
13899
13901template<typename CharType>
13902using output_adapter_t = std::shared_ptr<output_adapter_protocol<CharType>>;
13903
13905template<typename CharType, typename AllocatorType = std::allocator<CharType>>
13906class output_vector_adapter : public output_adapter_protocol<CharType>
13907{
13908 public:
13909 explicit output_vector_adapter(std::vector<CharType, AllocatorType>& vec) noexcept
13910 : v(vec)
13911 {}
13912
13913 void write_character(CharType c) override
13914 {
13915 v.push_back(c);
13916 }
13917
13919 void write_characters(const CharType* s, std::size_t length) override
13920 {
13921 std::copy(s, s + length, std::back_inserter(v));
13922 }
13923
13924 private:
13925 std::vector<CharType, AllocatorType>& v;
13926};
13927
13928#ifndef JSON_NO_IO
13930template<typename CharType>
13931class output_stream_adapter : public output_adapter_protocol<CharType>
13932{
13933 public:
13934 explicit output_stream_adapter(std::basic_ostream<CharType>& s) noexcept
13935 : stream(s)
13936 {}
13937
13938 void write_character(CharType c) override
13939 {
13940 stream.put(c);
13941 }
13942
13944 void write_characters(const CharType* s, std::size_t length) override
13945 {
13946 stream.write(s, static_cast<std::streamsize>(length));
13947 }
13948
13949 private:
13950 std::basic_ostream<CharType>& stream;
13951};
13952#endif // JSON_NO_IO
13953
13955template<typename CharType, typename StringType = std::basic_string<CharType>>
13956class output_string_adapter : public output_adapter_protocol<CharType>
13957{
13958 public:
13959 explicit output_string_adapter(StringType& s) noexcept
13960 : str(s)
13961 {}
13962
13963 void write_character(CharType c) override
13964 {
13965 str.push_back(c);
13966 }
13967
13969 void write_characters(const CharType* s, std::size_t length) override
13970 {
13971 str.append(s, length);
13972 }
13973
13974 private:
13975 StringType& str;
13976};
13977
13978template<typename CharType, typename StringType = std::basic_string<CharType>>
13979class output_adapter
13980{
13981 public:
13982 template<typename AllocatorType = std::allocator<CharType>>
13983 output_adapter(std::vector<CharType, AllocatorType>& vec)
13984 : oa(std::make_shared<output_vector_adapter<CharType, AllocatorType>>(vec)) {}
13985
13986#ifndef JSON_NO_IO
13987 output_adapter(std::basic_ostream<CharType>& s)
13988 : oa(std::make_shared<output_stream_adapter<CharType>>(s)) {}
13989#endif // JSON_NO_IO
13990
13991 output_adapter(StringType& s)
13992 : oa(std::make_shared<output_string_adapter<CharType, StringType>>(s)) {}
13993
13994 operator output_adapter_t<CharType>()
13995 {
13996 return oa;
13997 }
13998
13999 private:
14000 output_adapter_t<CharType> oa = nullptr;
14001};
14002} // namespace detail
14003} // namespace nlohmann
14004
14005// #include <nlohmann/detail/string_concat.hpp>
14006
14007
14008namespace nlohmann
14009{
14010namespace detail
14011{
14013// binary writer //
14015
14019template<typename BasicJsonType, typename CharType>
14020class binary_writer
14021{
14022 using string_t = typename BasicJsonType::string_t;
14023 using binary_t = typename BasicJsonType::binary_t;
14024 using number_float_t = typename BasicJsonType::number_float_t;
14025
14026 public:
14032 explicit binary_writer(output_adapter_t<CharType> adapter) : oa(std::move(adapter))
14033 {
14034 JSON_ASSERT(oa);
14035 }
14036
14041 void write_bson(const BasicJsonType& j)
14042 {
14043 switch (j.type())
14044 {
14045 case value_t::object:
14046 {
14047 write_bson_object(*j.m_value.object);
14048 break;
14049 }
14050
14051 case value_t::null:
14052 case value_t::array:
14053 case value_t::string:
14054 case value_t::boolean:
14055 case value_t::number_integer:
14056 case value_t::number_unsigned:
14057 case value_t::number_float:
14058 case value_t::binary:
14059 case value_t::discarded:
14060 default:
14061 {
14062 JSON_THROW(type_error::create(317, concat("to serialize to BSON, top-level type must be object, but is ", j.type_name()), &j));
14063 }
14064 }
14065 }
14066
14070 void write_cbor(const BasicJsonType& j)
14071 {
14072 switch (j.type())
14073 {
14074 case value_t::null:
14075 {
14076 oa->write_character(to_char_type(0xF6));
14077 break;
14078 }
14079
14080 case value_t::boolean:
14081 {
14082 oa->write_character(j.m_value.boolean
14083 ? to_char_type(0xF5)
14084 : to_char_type(0xF4));
14085 break;
14086 }
14087
14088 case value_t::number_integer:
14089 {
14090 if (j.m_value.number_integer >= 0)
14091 {
14092 // CBOR does not differentiate between positive signed
14093 // integers and unsigned integers. Therefore, we used the
14094 // code from the value_t::number_unsigned case here.
14095 if (j.m_value.number_integer <= 0x17)
14096 {
14097 write_number(static_cast<std::uint8_t>(j.m_value.number_integer));
14098 }
14099 else if (j.m_value.number_integer <= (std::numeric_limits<std::uint8_t>::max)())
14100 {
14101 oa->write_character(to_char_type(0x18));
14102 write_number(static_cast<std::uint8_t>(j.m_value.number_integer));
14103 }
14104 else if (j.m_value.number_integer <= (std::numeric_limits<std::uint16_t>::max)())
14105 {
14106 oa->write_character(to_char_type(0x19));
14107 write_number(static_cast<std::uint16_t>(j.m_value.number_integer));
14108 }
14109 else if (j.m_value.number_integer <= (std::numeric_limits<std::uint32_t>::max)())
14110 {
14111 oa->write_character(to_char_type(0x1A));
14112 write_number(static_cast<std::uint32_t>(j.m_value.number_integer));
14113 }
14114 else
14115 {
14116 oa->write_character(to_char_type(0x1B));
14117 write_number(static_cast<std::uint64_t>(j.m_value.number_integer));
14118 }
14119 }
14120 else
14121 {
14122 // The conversions below encode the sign in the first
14123 // byte, and the value is converted to a positive number.
14124 const auto positive_number = -1 - j.m_value.number_integer;
14125 if (j.m_value.number_integer >= -24)
14126 {
14127 write_number(static_cast<std::uint8_t>(0x20 + positive_number));
14128 }
14129 else if (positive_number <= (std::numeric_limits<std::uint8_t>::max)())
14130 {
14131 oa->write_character(to_char_type(0x38));
14132 write_number(static_cast<std::uint8_t>(positive_number));
14133 }
14134 else if (positive_number <= (std::numeric_limits<std::uint16_t>::max)())
14135 {
14136 oa->write_character(to_char_type(0x39));
14137 write_number(static_cast<std::uint16_t>(positive_number));
14138 }
14139 else if (positive_number <= (std::numeric_limits<std::uint32_t>::max)())
14140 {
14141 oa->write_character(to_char_type(0x3A));
14142 write_number(static_cast<std::uint32_t>(positive_number));
14143 }
14144 else
14145 {
14146 oa->write_character(to_char_type(0x3B));
14147 write_number(static_cast<std::uint64_t>(positive_number));
14148 }
14149 }
14150 break;
14151 }
14152
14153 case value_t::number_unsigned:
14154 {
14155 if (j.m_value.number_unsigned <= 0x17)
14156 {
14157 write_number(static_cast<std::uint8_t>(j.m_value.number_unsigned));
14158 }
14159 else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint8_t>::max)())
14160 {
14161 oa->write_character(to_char_type(0x18));
14162 write_number(static_cast<std::uint8_t>(j.m_value.number_unsigned));
14163 }
14164 else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint16_t>::max)())
14165 {
14166 oa->write_character(to_char_type(0x19));
14167 write_number(static_cast<std::uint16_t>(j.m_value.number_unsigned));
14168 }
14169 else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint32_t>::max)())
14170 {
14171 oa->write_character(to_char_type(0x1A));
14172 write_number(static_cast<std::uint32_t>(j.m_value.number_unsigned));
14173 }
14174 else
14175 {
14176 oa->write_character(to_char_type(0x1B));
14177 write_number(static_cast<std::uint64_t>(j.m_value.number_unsigned));
14178 }
14179 break;
14180 }
14181
14182 case value_t::number_float:
14183 {
14184 if (std::isnan(j.m_value.number_float))
14185 {
14186 // NaN is 0xf97e00 in CBOR
14187 oa->write_character(to_char_type(0xF9));
14188 oa->write_character(to_char_type(0x7E));
14189 oa->write_character(to_char_type(0x00));
14190 }
14191 else if (std::isinf(j.m_value.number_float))
14192 {
14193 // Infinity is 0xf97c00, -Infinity is 0xf9fc00
14194 oa->write_character(to_char_type(0xf9));
14195 oa->write_character(j.m_value.number_float > 0 ? to_char_type(0x7C) : to_char_type(0xFC));
14196 oa->write_character(to_char_type(0x00));
14197 }
14198 else
14199 {
14200 write_compact_float(j.m_value.number_float, detail::input_format_t::cbor);
14201 }
14202 break;
14203 }
14204
14205 case value_t::string:
14206 {
14207 // step 1: write control byte and the string length
14208 const auto N = j.m_value.string->size();
14209 if (N <= 0x17)
14210 {
14211 write_number(static_cast<std::uint8_t>(0x60 + N));
14212 }
14213 else if (N <= (std::numeric_limits<std::uint8_t>::max)())
14214 {
14215 oa->write_character(to_char_type(0x78));
14216 write_number(static_cast<std::uint8_t>(N));
14217 }
14218 else if (N <= (std::numeric_limits<std::uint16_t>::max)())
14219 {
14220 oa->write_character(to_char_type(0x79));
14221 write_number(static_cast<std::uint16_t>(N));
14222 }
14223 else if (N <= (std::numeric_limits<std::uint32_t>::max)())
14224 {
14225 oa->write_character(to_char_type(0x7A));
14226 write_number(static_cast<std::uint32_t>(N));
14227 }
14228 // LCOV_EXCL_START
14229 else if (N <= (std::numeric_limits<std::uint64_t>::max)())
14230 {
14231 oa->write_character(to_char_type(0x7B));
14232 write_number(static_cast<std::uint64_t>(N));
14233 }
14234 // LCOV_EXCL_STOP
14235
14236 // step 2: write the string
14237 oa->write_characters(
14238 reinterpret_cast<const CharType*>(j.m_value.string->c_str()),
14239 j.m_value.string->size());
14240 break;
14241 }
14242
14243 case value_t::array:
14244 {
14245 // step 1: write control byte and the array size
14246 const auto N = j.m_value.array->size();
14247 if (N <= 0x17)
14248 {
14249 write_number(static_cast<std::uint8_t>(0x80 + N));
14250 }
14251 else if (N <= (std::numeric_limits<std::uint8_t>::max)())
14252 {
14253 oa->write_character(to_char_type(0x98));
14254 write_number(static_cast<std::uint8_t>(N));
14255 }
14256 else if (N <= (std::numeric_limits<std::uint16_t>::max)())
14257 {
14258 oa->write_character(to_char_type(0x99));
14259 write_number(static_cast<std::uint16_t>(N));
14260 }
14261 else if (N <= (std::numeric_limits<std::uint32_t>::max)())
14262 {
14263 oa->write_character(to_char_type(0x9A));
14264 write_number(static_cast<std::uint32_t>(N));
14265 }
14266 // LCOV_EXCL_START
14267 else if (N <= (std::numeric_limits<std::uint64_t>::max)())
14268 {
14269 oa->write_character(to_char_type(0x9B));
14270 write_number(static_cast<std::uint64_t>(N));
14271 }
14272 // LCOV_EXCL_STOP
14273
14274 // step 2: write each element
14275 for (const auto& el : *j.m_value.array)
14276 {
14277 write_cbor(el);
14278 }
14279 break;
14280 }
14281
14282 case value_t::binary:
14283 {
14284 if (j.m_value.binary->has_subtype())
14285 {
14286 if (j.m_value.binary->subtype() <= (std::numeric_limits<std::uint8_t>::max)())
14287 {
14288 write_number(static_cast<std::uint8_t>(0xd8));
14289 write_number(static_cast<std::uint8_t>(j.m_value.binary->subtype()));
14290 }
14291 else if (j.m_value.binary->subtype() <= (std::numeric_limits<std::uint16_t>::max)())
14292 {
14293 write_number(static_cast<std::uint8_t>(0xd9));
14294 write_number(static_cast<std::uint16_t>(j.m_value.binary->subtype()));
14295 }
14296 else if (j.m_value.binary->subtype() <= (std::numeric_limits<std::uint32_t>::max)())
14297 {
14298 write_number(static_cast<std::uint8_t>(0xda));
14299 write_number(static_cast<std::uint32_t>(j.m_value.binary->subtype()));
14300 }
14301 else if (j.m_value.binary->subtype() <= (std::numeric_limits<std::uint64_t>::max)())
14302 {
14303 write_number(static_cast<std::uint8_t>(0xdb));
14304 write_number(static_cast<std::uint64_t>(j.m_value.binary->subtype()));
14305 }
14306 }
14307
14308 // step 1: write control byte and the binary array size
14309 const auto N = j.m_value.binary->size();
14310 if (N <= 0x17)
14311 {
14312 write_number(static_cast<std::uint8_t>(0x40 + N));
14313 }
14314 else if (N <= (std::numeric_limits<std::uint8_t>::max)())
14315 {
14316 oa->write_character(to_char_type(0x58));
14317 write_number(static_cast<std::uint8_t>(N));
14318 }
14319 else if (N <= (std::numeric_limits<std::uint16_t>::max)())
14320 {
14321 oa->write_character(to_char_type(0x59));
14322 write_number(static_cast<std::uint16_t>(N));
14323 }
14324 else if (N <= (std::numeric_limits<std::uint32_t>::max)())
14325 {
14326 oa->write_character(to_char_type(0x5A));
14327 write_number(static_cast<std::uint32_t>(N));
14328 }
14329 // LCOV_EXCL_START
14330 else if (N <= (std::numeric_limits<std::uint64_t>::max)())
14331 {
14332 oa->write_character(to_char_type(0x5B));
14333 write_number(static_cast<std::uint64_t>(N));
14334 }
14335 // LCOV_EXCL_STOP
14336
14337 // step 2: write each element
14338 oa->write_characters(
14339 reinterpret_cast<const CharType*>(j.m_value.binary->data()),
14340 N);
14341
14342 break;
14343 }
14344
14345 case value_t::object:
14346 {
14347 // step 1: write control byte and the object size
14348 const auto N = j.m_value.object->size();
14349 if (N <= 0x17)
14350 {
14351 write_number(static_cast<std::uint8_t>(0xA0 + N));
14352 }
14353 else if (N <= (std::numeric_limits<std::uint8_t>::max)())
14354 {
14355 oa->write_character(to_char_type(0xB8));
14356 write_number(static_cast<std::uint8_t>(N));
14357 }
14358 else if (N <= (std::numeric_limits<std::uint16_t>::max)())
14359 {
14360 oa->write_character(to_char_type(0xB9));
14361 write_number(static_cast<std::uint16_t>(N));
14362 }
14363 else if (N <= (std::numeric_limits<std::uint32_t>::max)())
14364 {
14365 oa->write_character(to_char_type(0xBA));
14366 write_number(static_cast<std::uint32_t>(N));
14367 }
14368 // LCOV_EXCL_START
14369 else if (N <= (std::numeric_limits<std::uint64_t>::max)())
14370 {
14371 oa->write_character(to_char_type(0xBB));
14372 write_number(static_cast<std::uint64_t>(N));
14373 }
14374 // LCOV_EXCL_STOP
14375
14376 // step 2: write each element
14377 for (const auto& el : *j.m_value.object)
14378 {
14379 write_cbor(el.first);
14380 write_cbor(el.second);
14381 }
14382 break;
14383 }
14384
14385 case value_t::discarded:
14386 default:
14387 break;
14388 }
14389 }
14390
14394 void write_msgpack(const BasicJsonType& j)
14395 {
14396 switch (j.type())
14397 {
14398 case value_t::null: // nil
14399 {
14400 oa->write_character(to_char_type(0xC0));
14401 break;
14402 }
14403
14404 case value_t::boolean: // true and false
14405 {
14406 oa->write_character(j.m_value.boolean
14407 ? to_char_type(0xC3)
14408 : to_char_type(0xC2));
14409 break;
14410 }
14411
14412 case value_t::number_integer:
14413 {
14414 if (j.m_value.number_integer >= 0)
14415 {
14416 // MessagePack does not differentiate between positive
14417 // signed integers and unsigned integers. Therefore, we used
14418 // the code from the value_t::number_unsigned case here.
14419 if (j.m_value.number_unsigned < 128)
14420 {
14421 // positive fixnum
14422 write_number(static_cast<std::uint8_t>(j.m_value.number_integer));
14423 }
14424 else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint8_t>::max)())
14425 {
14426 // uint 8
14427 oa->write_character(to_char_type(0xCC));
14428 write_number(static_cast<std::uint8_t>(j.m_value.number_integer));
14429 }
14430 else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint16_t>::max)())
14431 {
14432 // uint 16
14433 oa->write_character(to_char_type(0xCD));
14434 write_number(static_cast<std::uint16_t>(j.m_value.number_integer));
14435 }
14436 else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint32_t>::max)())
14437 {
14438 // uint 32
14439 oa->write_character(to_char_type(0xCE));
14440 write_number(static_cast<std::uint32_t>(j.m_value.number_integer));
14441 }
14442 else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint64_t>::max)())
14443 {
14444 // uint 64
14445 oa->write_character(to_char_type(0xCF));
14446 write_number(static_cast<std::uint64_t>(j.m_value.number_integer));
14447 }
14448 }
14449 else
14450 {
14451 if (j.m_value.number_integer >= -32)
14452 {
14453 // negative fixnum
14454 write_number(static_cast<std::int8_t>(j.m_value.number_integer));
14455 }
14456 else if (j.m_value.number_integer >= (std::numeric_limits<std::int8_t>::min)() &&
14457 j.m_value.number_integer <= (std::numeric_limits<std::int8_t>::max)())
14458 {
14459 // int 8
14460 oa->write_character(to_char_type(0xD0));
14461 write_number(static_cast<std::int8_t>(j.m_value.number_integer));
14462 }
14463 else if (j.m_value.number_integer >= (std::numeric_limits<std::int16_t>::min)() &&
14464 j.m_value.number_integer <= (std::numeric_limits<std::int16_t>::max)())
14465 {
14466 // int 16
14467 oa->write_character(to_char_type(0xD1));
14468 write_number(static_cast<std::int16_t>(j.m_value.number_integer));
14469 }
14470 else if (j.m_value.number_integer >= (std::numeric_limits<std::int32_t>::min)() &&
14471 j.m_value.number_integer <= (std::numeric_limits<std::int32_t>::max)())
14472 {
14473 // int 32
14474 oa->write_character(to_char_type(0xD2));
14475 write_number(static_cast<std::int32_t>(j.m_value.number_integer));
14476 }
14477 else if (j.m_value.number_integer >= (std::numeric_limits<std::int64_t>::min)() &&
14478 j.m_value.number_integer <= (std::numeric_limits<std::int64_t>::max)())
14479 {
14480 // int 64
14481 oa->write_character(to_char_type(0xD3));
14482 write_number(static_cast<std::int64_t>(j.m_value.number_integer));
14483 }
14484 }
14485 break;
14486 }
14487
14488 case value_t::number_unsigned:
14489 {
14490 if (j.m_value.number_unsigned < 128)
14491 {
14492 // positive fixnum
14493 write_number(static_cast<std::uint8_t>(j.m_value.number_integer));
14494 }
14495 else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint8_t>::max)())
14496 {
14497 // uint 8
14498 oa->write_character(to_char_type(0xCC));
14499 write_number(static_cast<std::uint8_t>(j.m_value.number_integer));
14500 }
14501 else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint16_t>::max)())
14502 {
14503 // uint 16
14504 oa->write_character(to_char_type(0xCD));
14505 write_number(static_cast<std::uint16_t>(j.m_value.number_integer));
14506 }
14507 else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint32_t>::max)())
14508 {
14509 // uint 32
14510 oa->write_character(to_char_type(0xCE));
14511 write_number(static_cast<std::uint32_t>(j.m_value.number_integer));
14512 }
14513 else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint64_t>::max)())
14514 {
14515 // uint 64
14516 oa->write_character(to_char_type(0xCF));
14517 write_number(static_cast<std::uint64_t>(j.m_value.number_integer));
14518 }
14519 break;
14520 }
14521
14522 case value_t::number_float:
14523 {
14524 write_compact_float(j.m_value.number_float, detail::input_format_t::msgpack);
14525 break;
14526 }
14527
14528 case value_t::string:
14529 {
14530 // step 1: write control byte and the string length
14531 const auto N = j.m_value.string->size();
14532 if (N <= 31)
14533 {
14534 // fixstr
14535 write_number(static_cast<std::uint8_t>(0xA0 | N));
14536 }
14537 else if (N <= (std::numeric_limits<std::uint8_t>::max)())
14538 {
14539 // str 8
14540 oa->write_character(to_char_type(0xD9));
14541 write_number(static_cast<std::uint8_t>(N));
14542 }
14543 else if (N <= (std::numeric_limits<std::uint16_t>::max)())
14544 {
14545 // str 16
14546 oa->write_character(to_char_type(0xDA));
14547 write_number(static_cast<std::uint16_t>(N));
14548 }
14549 else if (N <= (std::numeric_limits<std::uint32_t>::max)())
14550 {
14551 // str 32
14552 oa->write_character(to_char_type(0xDB));
14553 write_number(static_cast<std::uint32_t>(N));
14554 }
14555
14556 // step 2: write the string
14557 oa->write_characters(
14558 reinterpret_cast<const CharType*>(j.m_value.string->c_str()),
14559 j.m_value.string->size());
14560 break;
14561 }
14562
14563 case value_t::array:
14564 {
14565 // step 1: write control byte and the array size
14566 const auto N = j.m_value.array->size();
14567 if (N <= 15)
14568 {
14569 // fixarray
14570 write_number(static_cast<std::uint8_t>(0x90 | N));
14571 }
14572 else if (N <= (std::numeric_limits<std::uint16_t>::max)())
14573 {
14574 // array 16
14575 oa->write_character(to_char_type(0xDC));
14576 write_number(static_cast<std::uint16_t>(N));
14577 }
14578 else if (N <= (std::numeric_limits<std::uint32_t>::max)())
14579 {
14580 // array 32
14581 oa->write_character(to_char_type(0xDD));
14582 write_number(static_cast<std::uint32_t>(N));
14583 }
14584
14585 // step 2: write each element
14586 for (const auto& el : *j.m_value.array)
14587 {
14588 write_msgpack(el);
14589 }
14590 break;
14591 }
14592
14593 case value_t::binary:
14594 {
14595 // step 0: determine if the binary type has a set subtype to
14596 // determine whether or not to use the ext or fixext types
14597 const bool use_ext = j.m_value.binary->has_subtype();
14598
14599 // step 1: write control byte and the byte string length
14600 const auto N = j.m_value.binary->size();
14601 if (N <= (std::numeric_limits<std::uint8_t>::max)())
14602 {
14603 std::uint8_t output_type{};
14604 bool fixed = true;
14605 if (use_ext)
14606 {
14607 switch (N)
14608 {
14609 case 1:
14610 output_type = 0xD4; // fixext 1
14611 break;
14612 case 2:
14613 output_type = 0xD5; // fixext 2
14614 break;
14615 case 4:
14616 output_type = 0xD6; // fixext 4
14617 break;
14618 case 8:
14619 output_type = 0xD7; // fixext 8
14620 break;
14621 case 16:
14622 output_type = 0xD8; // fixext 16
14623 break;
14624 default:
14625 output_type = 0xC7; // ext 8
14626 fixed = false;
14627 break;
14628 }
14629
14630 }
14631 else
14632 {
14633 output_type = 0xC4; // bin 8
14634 fixed = false;
14635 }
14636
14637 oa->write_character(to_char_type(output_type));
14638 if (!fixed)
14639 {
14640 write_number(static_cast<std::uint8_t>(N));
14641 }
14642 }
14643 else if (N <= (std::numeric_limits<std::uint16_t>::max)())
14644 {
14645 std::uint8_t output_type = use_ext
14646 ? 0xC8 // ext 16
14647 : 0xC5; // bin 16
14648
14649 oa->write_character(to_char_type(output_type));
14650 write_number(static_cast<std::uint16_t>(N));
14651 }
14652 else if (N <= (std::numeric_limits<std::uint32_t>::max)())
14653 {
14654 std::uint8_t output_type = use_ext
14655 ? 0xC9 // ext 32
14656 : 0xC6; // bin 32
14657
14658 oa->write_character(to_char_type(output_type));
14659 write_number(static_cast<std::uint32_t>(N));
14660 }
14661
14662 // step 1.5: if this is an ext type, write the subtype
14663 if (use_ext)
14664 {
14665 write_number(static_cast<std::int8_t>(j.m_value.binary->subtype()));
14666 }
14667
14668 // step 2: write the byte string
14669 oa->write_characters(
14670 reinterpret_cast<const CharType*>(j.m_value.binary->data()),
14671 N);
14672
14673 break;
14674 }
14675
14676 case value_t::object:
14677 {
14678 // step 1: write control byte and the object size
14679 const auto N = j.m_value.object->size();
14680 if (N <= 15)
14681 {
14682 // fixmap
14683 write_number(static_cast<std::uint8_t>(0x80 | (N & 0xF)));
14684 }
14685 else if (N <= (std::numeric_limits<std::uint16_t>::max)())
14686 {
14687 // map 16
14688 oa->write_character(to_char_type(0xDE));
14689 write_number(static_cast<std::uint16_t>(N));
14690 }
14691 else if (N <= (std::numeric_limits<std::uint32_t>::max)())
14692 {
14693 // map 32
14694 oa->write_character(to_char_type(0xDF));
14695 write_number(static_cast<std::uint32_t>(N));
14696 }
14697
14698 // step 2: write each element
14699 for (const auto& el : *j.m_value.object)
14700 {
14701 write_msgpack(el.first);
14702 write_msgpack(el.second);
14703 }
14704 break;
14705 }
14706
14707 case value_t::discarded:
14708 default:
14709 break;
14710 }
14711 }
14712
14720 void write_ubjson(const BasicJsonType& j, const bool use_count,
14721 const bool use_type, const bool add_prefix = true,
14722 const bool use_bjdata = false)
14723 {
14724 switch (j.type())
14725 {
14726 case value_t::null:
14727 {
14728 if (add_prefix)
14729 {
14730 oa->write_character(to_char_type('Z'));
14731 }
14732 break;
14733 }
14734
14735 case value_t::boolean:
14736 {
14737 if (add_prefix)
14738 {
14739 oa->write_character(j.m_value.boolean
14740 ? to_char_type('T')
14741 : to_char_type('F'));
14742 }
14743 break;
14744 }
14745
14746 case value_t::number_integer:
14747 {
14748 write_number_with_ubjson_prefix(j.m_value.number_integer, add_prefix, use_bjdata);
14749 break;
14750 }
14751
14752 case value_t::number_unsigned:
14753 {
14754 write_number_with_ubjson_prefix(j.m_value.number_unsigned, add_prefix, use_bjdata);
14755 break;
14756 }
14757
14758 case value_t::number_float:
14759 {
14760 write_number_with_ubjson_prefix(j.m_value.number_float, add_prefix, use_bjdata);
14761 break;
14762 }
14763
14764 case value_t::string:
14765 {
14766 if (add_prefix)
14767 {
14768 oa->write_character(to_char_type('S'));
14769 }
14770 write_number_with_ubjson_prefix(j.m_value.string->size(), true, use_bjdata);
14771 oa->write_characters(
14772 reinterpret_cast<const CharType*>(j.m_value.string->c_str()),
14773 j.m_value.string->size());
14774 break;
14775 }
14776
14777 case value_t::array:
14778 {
14779 if (add_prefix)
14780 {
14781 oa->write_character(to_char_type('['));
14782 }
14783
14784 bool prefix_required = true;
14785 if (use_type && !j.m_value.array->empty())
14786 {
14787 JSON_ASSERT(use_count);
14788 const CharType first_prefix = ubjson_prefix(j.front(), use_bjdata);
14789 const bool same_prefix = std::all_of(j.begin() + 1, j.end(),
14790 [this, first_prefix, use_bjdata](const BasicJsonType & v)
14791 {
14792 return ubjson_prefix(v, use_bjdata) == first_prefix;
14793 });
14794
14795 std::vector<CharType> bjdx = {'[', '{', 'S', 'H', 'T', 'F', 'N', 'Z'}; // excluded markers in bjdata optimized type
14796
14797 if (same_prefix && !(use_bjdata && std::find(bjdx.begin(), bjdx.end(), first_prefix) != bjdx.end()))
14798 {
14799 prefix_required = false;
14800 oa->write_character(to_char_type('$'));
14801 oa->write_character(first_prefix);
14802 }
14803 }
14804
14805 if (use_count)
14806 {
14807 oa->write_character(to_char_type('#'));
14808 write_number_with_ubjson_prefix(j.m_value.array->size(), true, use_bjdata);
14809 }
14810
14811 for (const auto& el : *j.m_value.array)
14812 {
14813 write_ubjson(el, use_count, use_type, prefix_required, use_bjdata);
14814 }
14815
14816 if (!use_count)
14817 {
14818 oa->write_character(to_char_type(']'));
14819 }
14820
14821 break;
14822 }
14823
14824 case value_t::binary:
14825 {
14826 if (add_prefix)
14827 {
14828 oa->write_character(to_char_type('['));
14829 }
14830
14831 if (use_type && !j.m_value.binary->empty())
14832 {
14833 JSON_ASSERT(use_count);
14834 oa->write_character(to_char_type('$'));
14835 oa->write_character('U');
14836 }
14837
14838 if (use_count)
14839 {
14840 oa->write_character(to_char_type('#'));
14841 write_number_with_ubjson_prefix(j.m_value.binary->size(), true, use_bjdata);
14842 }
14843
14844 if (use_type)
14845 {
14846 oa->write_characters(
14847 reinterpret_cast<const CharType*>(j.m_value.binary->data()),
14848 j.m_value.binary->size());
14849 }
14850 else
14851 {
14852 for (size_t i = 0; i < j.m_value.binary->size(); ++i)
14853 {
14854 oa->write_character(to_char_type('U'));
14855 oa->write_character(j.m_value.binary->data()[i]);
14856 }
14857 }
14858
14859 if (!use_count)
14860 {
14861 oa->write_character(to_char_type(']'));
14862 }
14863
14864 break;
14865 }
14866
14867 case value_t::object:
14868 {
14869 if (use_bjdata && j.m_value.object->size() == 3 && j.m_value.object->find("_ArrayType_") != j.m_value.object->end() && j.m_value.object->find("_ArraySize_") != j.m_value.object->end() && j.m_value.object->find("_ArrayData_") != j.m_value.object->end())
14870 {
14871 if (!write_bjdata_ndarray(*j.m_value.object, use_count, use_type)) // decode bjdata ndarray in the JData format (https://github.com/NeuroJSON/jdata)
14872 {
14873 break;
14874 }
14875 }
14876
14877 if (add_prefix)
14878 {
14879 oa->write_character(to_char_type('{'));
14880 }
14881
14882 bool prefix_required = true;
14883 if (use_type && !j.m_value.object->empty())
14884 {
14885 JSON_ASSERT(use_count);
14886 const CharType first_prefix = ubjson_prefix(j.front(), use_bjdata);
14887 const bool same_prefix = std::all_of(j.begin(), j.end(),
14888 [this, first_prefix, use_bjdata](const BasicJsonType & v)
14889 {
14890 return ubjson_prefix(v, use_bjdata) == first_prefix;
14891 });
14892
14893 std::vector<CharType> bjdx = {'[', '{', 'S', 'H', 'T', 'F', 'N', 'Z'}; // excluded markers in bjdata optimized type
14894
14895 if (same_prefix && !(use_bjdata && std::find(bjdx.begin(), bjdx.end(), first_prefix) != bjdx.end()))
14896 {
14897 prefix_required = false;
14898 oa->write_character(to_char_type('$'));
14899 oa->write_character(first_prefix);
14900 }
14901 }
14902
14903 if (use_count)
14904 {
14905 oa->write_character(to_char_type('#'));
14906 write_number_with_ubjson_prefix(j.m_value.object->size(), true, use_bjdata);
14907 }
14908
14909 for (const auto& el : *j.m_value.object)
14910 {
14911 write_number_with_ubjson_prefix(el.first.size(), true, use_bjdata);
14912 oa->write_characters(
14913 reinterpret_cast<const CharType*>(el.first.c_str()),
14914 el.first.size());
14915 write_ubjson(el.second, use_count, use_type, prefix_required, use_bjdata);
14916 }
14917
14918 if (!use_count)
14919 {
14920 oa->write_character(to_char_type('}'));
14921 }
14922
14923 break;
14924 }
14925
14926 case value_t::discarded:
14927 default:
14928 break;
14929 }
14930 }
14931
14932 private:
14934 // BSON //
14936
14941 static std::size_t calc_bson_entry_header_size(const string_t& name, const BasicJsonType& j)
14942 {
14943 const auto it = name.find(static_cast<typename string_t::value_type>(0));
14944 if (JSON_HEDLEY_UNLIKELY(it != BasicJsonType::string_t::npos))
14945 {
14946 JSON_THROW(out_of_range::create(409, concat("BSON key cannot contain code point U+0000 (at byte ", std::to_string(it), ")"), &j));
14947 static_cast<void>(j);
14948 }
14949
14950 return /*id*/ 1ul + name.size() + /*zero-terminator*/1u;
14951 }
14952
14956 void write_bson_entry_header(const string_t& name,
14957 const std::uint8_t element_type)
14958 {
14959 oa->write_character(to_char_type(element_type)); // boolean
14960 oa->write_characters(
14961 reinterpret_cast<const CharType*>(name.c_str()),
14962 name.size() + 1u);
14963 }
14964
14968 void write_bson_boolean(const string_t& name,
14969 const bool value)
14970 {
14971 write_bson_entry_header(name, 0x08);
14972 oa->write_character(value ? to_char_type(0x01) : to_char_type(0x00));
14973 }
14974
14978 void write_bson_double(const string_t& name,
14979 const double value)
14980 {
14981 write_bson_entry_header(name, 0x01);
14982 write_number<double>(value, true);
14983 }
14984
14988 static std::size_t calc_bson_string_size(const string_t& value)
14989 {
14990 return sizeof(std::int32_t) + value.size() + 1ul;
14991 }
14992
14996 void write_bson_string(const string_t& name,
14997 const string_t& value)
14998 {
14999 write_bson_entry_header(name, 0x02);
15000
15001 write_number<std::int32_t>(static_cast<std::int32_t>(value.size() + 1ul), true);
15002 oa->write_characters(
15003 reinterpret_cast<const CharType*>(value.c_str()),
15004 value.size() + 1);
15005 }
15006
15010 void write_bson_null(const string_t& name)
15011 {
15012 write_bson_entry_header(name, 0x0A);
15013 }
15014
15018 static std::size_t calc_bson_integer_size(const std::int64_t value)
15019 {
15020 return (std::numeric_limits<std::int32_t>::min)() <= value && value <= (std::numeric_limits<std::int32_t>::max)()
15021 ? sizeof(std::int32_t)
15022 : sizeof(std::int64_t);
15023 }
15024
15028 void write_bson_integer(const string_t& name,
15029 const std::int64_t value)
15030 {
15031 if ((std::numeric_limits<std::int32_t>::min)() <= value && value <= (std::numeric_limits<std::int32_t>::max)())
15032 {
15033 write_bson_entry_header(name, 0x10); // int32
15034 write_number<std::int32_t>(static_cast<std::int32_t>(value), true);
15035 }
15036 else
15037 {
15038 write_bson_entry_header(name, 0x12); // int64
15039 write_number<std::int64_t>(static_cast<std::int64_t>(value), true);
15040 }
15041 }
15042
15046 static constexpr std::size_t calc_bson_unsigned_size(const std::uint64_t value) noexcept
15047 {
15048 return (value <= static_cast<std::uint64_t>((std::numeric_limits<std::int32_t>::max)()))
15049 ? sizeof(std::int32_t)
15050 : sizeof(std::int64_t);
15051 }
15052
15056 void write_bson_unsigned(const string_t& name,
15057 const BasicJsonType& j)
15058 {
15059 if (j.m_value.number_unsigned <= static_cast<std::uint64_t>((std::numeric_limits<std::int32_t>::max)()))
15060 {
15061 write_bson_entry_header(name, 0x10 /* int32 */);
15062 write_number<std::int32_t>(static_cast<std::int32_t>(j.m_value.number_unsigned), true);
15063 }
15064 else if (j.m_value.number_unsigned <= static_cast<std::uint64_t>((std::numeric_limits<std::int64_t>::max)()))
15065 {
15066 write_bson_entry_header(name, 0x12 /* int64 */);
15067 write_number<std::int64_t>(static_cast<std::int64_t>(j.m_value.number_unsigned), true);
15068 }
15069 else
15070 {
15071 JSON_THROW(out_of_range::create(407, concat("integer number ", std::to_string(j.m_value.number_unsigned), " cannot be represented by BSON as it does not fit int64"), &j));
15072 }
15073 }
15074
15078 void write_bson_object_entry(const string_t& name,
15079 const typename BasicJsonType::object_t& value)
15080 {
15081 write_bson_entry_header(name, 0x03); // object
15082 write_bson_object(value);
15083 }
15084
15088 static std::size_t calc_bson_array_size(const typename BasicJsonType::array_t& value)
15089 {
15090 std::size_t array_index = 0ul;
15091
15092 const std::size_t embedded_document_size = std::accumulate(std::begin(value), std::end(value), static_cast<std::size_t>(0), [&array_index](std::size_t result, const typename BasicJsonType::array_t::value_type & el)
15093 {
15094 return result + calc_bson_element_size(std::to_string(array_index++), el);
15095 });
15096
15097 return sizeof(std::int32_t) + embedded_document_size + 1ul;
15098 }
15099
15103 static std::size_t calc_bson_binary_size(const typename BasicJsonType::binary_t& value)
15104 {
15105 return sizeof(std::int32_t) + value.size() + 1ul;
15106 }
15107
15111 void write_bson_array(const string_t& name,
15112 const typename BasicJsonType::array_t& value)
15113 {
15114 write_bson_entry_header(name, 0x04); // array
15115 write_number<std::int32_t>(static_cast<std::int32_t>(calc_bson_array_size(value)), true);
15116
15117 std::size_t array_index = 0ul;
15118
15119 for (const auto& el : value)
15120 {
15121 write_bson_element(std::to_string(array_index++), el);
15122 }
15123
15124 oa->write_character(to_char_type(0x00));
15125 }
15126
15130 void write_bson_binary(const string_t& name,
15131 const binary_t& value)
15132 {
15133 write_bson_entry_header(name, 0x05);
15134
15135 write_number<std::int32_t>(static_cast<std::int32_t>(value.size()), true);
15136 write_number(value.has_subtype() ? static_cast<std::uint8_t>(value.subtype()) : static_cast<std::uint8_t>(0x00));
15137
15138 oa->write_characters(reinterpret_cast<const CharType*>(value.data()), value.size());
15139 }
15140
15145 static std::size_t calc_bson_element_size(const string_t& name,
15146 const BasicJsonType& j)
15147 {
15148 const auto header_size = calc_bson_entry_header_size(name, j);
15149 switch (j.type())
15150 {
15151 case value_t::object:
15152 return header_size + calc_bson_object_size(*j.m_value.object);
15153
15154 case value_t::array:
15155 return header_size + calc_bson_array_size(*j.m_value.array);
15156
15157 case value_t::binary:
15158 return header_size + calc_bson_binary_size(*j.m_value.binary);
15159
15160 case value_t::boolean:
15161 return header_size + 1ul;
15162
15163 case value_t::number_float:
15164 return header_size + 8ul;
15165
15166 case value_t::number_integer:
15167 return header_size + calc_bson_integer_size(j.m_value.number_integer);
15168
15169 case value_t::number_unsigned:
15170 return header_size + calc_bson_unsigned_size(j.m_value.number_unsigned);
15171
15172 case value_t::string:
15173 return header_size + calc_bson_string_size(*j.m_value.string);
15174
15175 case value_t::null:
15176 return header_size + 0ul;
15177
15178 // LCOV_EXCL_START
15179 case value_t::discarded:
15180 default:
15181 JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert)
15182 return 0ul;
15183 // LCOV_EXCL_STOP
15184 }
15185 }
15186
15193 void write_bson_element(const string_t& name,
15194 const BasicJsonType& j)
15195 {
15196 switch (j.type())
15197 {
15198 case value_t::object:
15199 return write_bson_object_entry(name, *j.m_value.object);
15200
15201 case value_t::array:
15202 return write_bson_array(name, *j.m_value.array);
15203
15204 case value_t::binary:
15205 return write_bson_binary(name, *j.m_value.binary);
15206
15207 case value_t::boolean:
15208 return write_bson_boolean(name, j.m_value.boolean);
15209
15210 case value_t::number_float:
15211 return write_bson_double(name, j.m_value.number_float);
15212
15213 case value_t::number_integer:
15214 return write_bson_integer(name, j.m_value.number_integer);
15215
15216 case value_t::number_unsigned:
15217 return write_bson_unsigned(name, j);
15218
15219 case value_t::string:
15220 return write_bson_string(name, *j.m_value.string);
15221
15222 case value_t::null:
15223 return write_bson_null(name);
15224
15225 // LCOV_EXCL_START
15226 case value_t::discarded:
15227 default:
15228 JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert)
15229 return;
15230 // LCOV_EXCL_STOP
15231 }
15232 }
15233
15240 static std::size_t calc_bson_object_size(const typename BasicJsonType::object_t& value)
15241 {
15242 std::size_t document_size = std::accumulate(value.begin(), value.end(), static_cast<std::size_t>(0),
15243 [](size_t result, const typename BasicJsonType::object_t::value_type & el)
15244 {
15245 return result += calc_bson_element_size(el.first, el.second);
15246 });
15247
15248 return sizeof(std::int32_t) + document_size + 1ul;
15249 }
15250
15255 void write_bson_object(const typename BasicJsonType::object_t& value)
15256 {
15257 write_number<std::int32_t>(static_cast<std::int32_t>(calc_bson_object_size(value)), true);
15258
15259 for (const auto& el : value)
15260 {
15261 write_bson_element(el.first, el.second);
15262 }
15263
15264 oa->write_character(to_char_type(0x00));
15265 }
15266
15268 // CBOR //
15270
15271 static constexpr CharType get_cbor_float_prefix(float /*unused*/)
15272 {
15273 return to_char_type(0xFA); // Single-Precision Float
15274 }
15275
15276 static constexpr CharType get_cbor_float_prefix(double /*unused*/)
15277 {
15278 return to_char_type(0xFB); // Double-Precision Float
15279 }
15280
15282 // MsgPack //
15284
15285 static constexpr CharType get_msgpack_float_prefix(float /*unused*/)
15286 {
15287 return to_char_type(0xCA); // float 32
15288 }
15289
15290 static constexpr CharType get_msgpack_float_prefix(double /*unused*/)
15291 {
15292 return to_char_type(0xCB); // float 64
15293 }
15294
15296 // UBJSON //
15298
15299 // UBJSON: write number (floating point)
15300 template<typename NumberType, typename std::enable_if<
15301 std::is_floating_point<NumberType>::value, int>::type = 0>
15302 void write_number_with_ubjson_prefix(const NumberType n,
15303 const bool add_prefix,
15304 const bool use_bjdata)
15305 {
15306 if (add_prefix)
15307 {
15308 oa->write_character(get_ubjson_float_prefix(n));
15309 }
15310 write_number(n, use_bjdata);
15311 }
15312
15313 // UBJSON: write number (unsigned integer)
15314 template<typename NumberType, typename std::enable_if<
15315 std::is_unsigned<NumberType>::value, int>::type = 0>
15316 void write_number_with_ubjson_prefix(const NumberType n,
15317 const bool add_prefix,
15318 const bool use_bjdata)
15319 {
15320 if (n <= static_cast<std::uint64_t>((std::numeric_limits<std::int8_t>::max)()))
15321 {
15322 if (add_prefix)
15323 {
15324 oa->write_character(to_char_type('i')); // int8
15325 }
15326 write_number(static_cast<std::uint8_t>(n), use_bjdata);
15327 }
15328 else if (n <= (std::numeric_limits<std::uint8_t>::max)())
15329 {
15330 if (add_prefix)
15331 {
15332 oa->write_character(to_char_type('U')); // uint8
15333 }
15334 write_number(static_cast<std::uint8_t>(n), use_bjdata);
15335 }
15336 else if (n <= static_cast<std::uint64_t>((std::numeric_limits<std::int16_t>::max)()))
15337 {
15338 if (add_prefix)
15339 {
15340 oa->write_character(to_char_type('I')); // int16
15341 }
15342 write_number(static_cast<std::int16_t>(n), use_bjdata);
15343 }
15344 else if (use_bjdata && n <= static_cast<uint64_t>((std::numeric_limits<uint16_t>::max)()))
15345 {
15346 if (add_prefix)
15347 {
15348 oa->write_character(to_char_type('u')); // uint16 - bjdata only
15349 }
15350 write_number(static_cast<std::uint16_t>(n), use_bjdata);
15351 }
15352 else if (n <= static_cast<std::uint64_t>((std::numeric_limits<std::int32_t>::max)()))
15353 {
15354 if (add_prefix)
15355 {
15356 oa->write_character(to_char_type('l')); // int32
15357 }
15358 write_number(static_cast<std::int32_t>(n), use_bjdata);
15359 }
15360 else if (use_bjdata && n <= static_cast<uint64_t>((std::numeric_limits<uint32_t>::max)()))
15361 {
15362 if (add_prefix)
15363 {
15364 oa->write_character(to_char_type('m')); // uint32 - bjdata only
15365 }
15366 write_number(static_cast<std::uint32_t>(n), use_bjdata);
15367 }
15368 else if (n <= static_cast<std::uint64_t>((std::numeric_limits<std::int64_t>::max)()))
15369 {
15370 if (add_prefix)
15371 {
15372 oa->write_character(to_char_type('L')); // int64
15373 }
15374 write_number(static_cast<std::int64_t>(n), use_bjdata);
15375 }
15376 else if (use_bjdata && n <= (std::numeric_limits<uint64_t>::max)())
15377 {
15378 if (add_prefix)
15379 {
15380 oa->write_character(to_char_type('M')); // uint64 - bjdata only
15381 }
15382 write_number(static_cast<std::uint64_t>(n), use_bjdata);
15383 }
15384 else
15385 {
15386 if (add_prefix)
15387 {
15388 oa->write_character(to_char_type('H')); // high-precision number
15389 }
15390
15391 const auto number = BasicJsonType(n).dump();
15392 write_number_with_ubjson_prefix(number.size(), true, use_bjdata);
15393 for (std::size_t i = 0; i < number.size(); ++i)
15394 {
15395 oa->write_character(to_char_type(static_cast<std::uint8_t>(number[i])));
15396 }
15397 }
15398 }
15399
15400 // UBJSON: write number (signed integer)
15401 template < typename NumberType, typename std::enable_if <
15402 std::is_signed<NumberType>::value&&
15403 !std::is_floating_point<NumberType>::value, int >::type = 0 >
15404 void write_number_with_ubjson_prefix(const NumberType n,
15405 const bool add_prefix,
15406 const bool use_bjdata)
15407 {
15408 if ((std::numeric_limits<std::int8_t>::min)() <= n && n <= (std::numeric_limits<std::int8_t>::max)())
15409 {
15410 if (add_prefix)
15411 {
15412 oa->write_character(to_char_type('i')); // int8
15413 }
15414 write_number(static_cast<std::int8_t>(n), use_bjdata);
15415 }
15416 else if (static_cast<std::int64_t>((std::numeric_limits<std::uint8_t>::min)()) <= n && n <= static_cast<std::int64_t>((std::numeric_limits<std::uint8_t>::max)()))
15417 {
15418 if (add_prefix)
15419 {
15420 oa->write_character(to_char_type('U')); // uint8
15421 }
15422 write_number(static_cast<std::uint8_t>(n), use_bjdata);
15423 }
15424 else if ((std::numeric_limits<std::int16_t>::min)() <= n && n <= (std::numeric_limits<std::int16_t>::max)())
15425 {
15426 if (add_prefix)
15427 {
15428 oa->write_character(to_char_type('I')); // int16
15429 }
15430 write_number(static_cast<std::int16_t>(n), use_bjdata);
15431 }
15432 else if (use_bjdata && (static_cast<std::int64_t>((std::numeric_limits<std::uint16_t>::min)()) <= n && n <= static_cast<std::int64_t>((std::numeric_limits<std::uint16_t>::max)())))
15433 {
15434 if (add_prefix)
15435 {
15436 oa->write_character(to_char_type('u')); // uint16 - bjdata only
15437 }
15438 write_number(static_cast<uint16_t>(n), use_bjdata);
15439 }
15440 else if ((std::numeric_limits<std::int32_t>::min)() <= n && n <= (std::numeric_limits<std::int32_t>::max)())
15441 {
15442 if (add_prefix)
15443 {
15444 oa->write_character(to_char_type('l')); // int32
15445 }
15446 write_number(static_cast<std::int32_t>(n), use_bjdata);
15447 }
15448 else if (use_bjdata && (static_cast<std::int64_t>((std::numeric_limits<std::uint32_t>::min)()) <= n && n <= static_cast<std::int64_t>((std::numeric_limits<std::uint32_t>::max)())))
15449 {
15450 if (add_prefix)
15451 {
15452 oa->write_character(to_char_type('m')); // uint32 - bjdata only
15453 }
15454 write_number(static_cast<uint32_t>(n), use_bjdata);
15455 }
15456 else if ((std::numeric_limits<std::int64_t>::min)() <= n && n <= (std::numeric_limits<std::int64_t>::max)())
15457 {
15458 if (add_prefix)
15459 {
15460 oa->write_character(to_char_type('L')); // int64
15461 }
15462 write_number(static_cast<std::int64_t>(n), use_bjdata);
15463 }
15464 // LCOV_EXCL_START
15465 else
15466 {
15467 if (add_prefix)
15468 {
15469 oa->write_character(to_char_type('H')); // high-precision number
15470 }
15471
15472 const auto number = BasicJsonType(n).dump();
15473 write_number_with_ubjson_prefix(number.size(), true, use_bjdata);
15474 for (std::size_t i = 0; i < number.size(); ++i)
15475 {
15476 oa->write_character(to_char_type(static_cast<std::uint8_t>(number[i])));
15477 }
15478 }
15479 // LCOV_EXCL_STOP
15480 }
15481
15485 CharType ubjson_prefix(const BasicJsonType& j, const bool use_bjdata) const noexcept
15486 {
15487 switch (j.type())
15488 {
15489 case value_t::null:
15490 return 'Z';
15491
15492 case value_t::boolean:
15493 return j.m_value.boolean ? 'T' : 'F';
15494
15495 case value_t::number_integer:
15496 {
15497 if ((std::numeric_limits<std::int8_t>::min)() <= j.m_value.number_integer && j.m_value.number_integer <= (std::numeric_limits<std::int8_t>::max)())
15498 {
15499 return 'i';
15500 }
15501 if ((std::numeric_limits<std::uint8_t>::min)() <= j.m_value.number_integer && j.m_value.number_integer <= (std::numeric_limits<std::uint8_t>::max)())
15502 {
15503 return 'U';
15504 }
15505 if ((std::numeric_limits<std::int16_t>::min)() <= j.m_value.number_integer && j.m_value.number_integer <= (std::numeric_limits<std::int16_t>::max)())
15506 {
15507 return 'I';
15508 }
15509 if (use_bjdata && ((std::numeric_limits<std::uint16_t>::min)() <= j.m_value.number_integer && j.m_value.number_integer <= (std::numeric_limits<std::uint16_t>::max)()))
15510 {
15511 return 'u';
15512 }
15513 if ((std::numeric_limits<std::int32_t>::min)() <= j.m_value.number_integer && j.m_value.number_integer <= (std::numeric_limits<std::int32_t>::max)())
15514 {
15515 return 'l';
15516 }
15517 if (use_bjdata && ((std::numeric_limits<std::uint32_t>::min)() <= j.m_value.number_integer && j.m_value.number_integer <= (std::numeric_limits<std::uint32_t>::max)()))
15518 {
15519 return 'm';
15520 }
15521 if ((std::numeric_limits<std::int64_t>::min)() <= j.m_value.number_integer && j.m_value.number_integer <= (std::numeric_limits<std::int64_t>::max)())
15522 {
15523 return 'L';
15524 }
15525 // anything else is treated as high-precision number
15526 return 'H'; // LCOV_EXCL_LINE
15527 }
15528
15529 case value_t::number_unsigned:
15530 {
15531 if (j.m_value.number_unsigned <= static_cast<std::uint64_t>((std::numeric_limits<std::int8_t>::max)()))
15532 {
15533 return 'i';
15534 }
15535 if (j.m_value.number_unsigned <= static_cast<std::uint64_t>((std::numeric_limits<std::uint8_t>::max)()))
15536 {
15537 return 'U';
15538 }
15539 if (j.m_value.number_unsigned <= static_cast<std::uint64_t>((std::numeric_limits<std::int16_t>::max)()))
15540 {
15541 return 'I';
15542 }
15543 if (use_bjdata && j.m_value.number_unsigned <= static_cast<std::uint64_t>((std::numeric_limits<std::uint16_t>::max)()))
15544 {
15545 return 'u';
15546 }
15547 if (j.m_value.number_unsigned <= static_cast<std::uint64_t>((std::numeric_limits<std::int32_t>::max)()))
15548 {
15549 return 'l';
15550 }
15551 if (use_bjdata && j.m_value.number_unsigned <= static_cast<std::uint64_t>((std::numeric_limits<std::uint32_t>::max)()))
15552 {
15553 return 'm';
15554 }
15555 if (j.m_value.number_unsigned <= static_cast<std::uint64_t>((std::numeric_limits<std::int64_t>::max)()))
15556 {
15557 return 'L';
15558 }
15559 if (use_bjdata && j.m_value.number_unsigned <= (std::numeric_limits<std::uint64_t>::max)())
15560 {
15561 return 'M';
15562 }
15563 // anything else is treated as high-precision number
15564 return 'H'; // LCOV_EXCL_LINE
15565 }
15566
15567 case value_t::number_float:
15568 return get_ubjson_float_prefix(j.m_value.number_float);
15569
15570 case value_t::string:
15571 return 'S';
15572
15573 case value_t::array: // fallthrough
15574 case value_t::binary:
15575 return '[';
15576
15577 case value_t::object:
15578 return '{';
15579
15580 case value_t::discarded:
15581 default: // discarded values
15582 return 'N';
15583 }
15584 }
15585
15586 static constexpr CharType get_ubjson_float_prefix(float /*unused*/)
15587 {
15588 return 'd'; // float 32
15589 }
15590
15591 static constexpr CharType get_ubjson_float_prefix(double /*unused*/)
15592 {
15593 return 'D'; // float 64
15594 }
15595
15599 bool write_bjdata_ndarray(const typename BasicJsonType::object_t& value, const bool use_count, const bool use_type)
15600 {
15601 std::map<string_t, CharType> bjdtype = {{"uint8", 'U'}, {"int8", 'i'}, {"uint16", 'u'}, {"int16", 'I'},
15602 {"uint32", 'm'}, {"int32", 'l'}, {"uint64", 'M'}, {"int64", 'L'}, {"single", 'd'}, {"double", 'D'}, {"char", 'C'}
15603 };
15604
15605 string_t key = "_ArrayType_";
15606 auto it = bjdtype.find(static_cast<string_t>(value.at(key)));
15607 if (it == bjdtype.end())
15608 {
15609 return true;
15610 }
15611 CharType dtype = it->second;
15612
15613 key = "_ArraySize_";
15614 std::size_t len = (value.at(key).empty() ? 0 : 1);
15615 for (const auto& el : value.at(key))
15616 {
15617 len *= static_cast<std::size_t>(el.m_value.number_unsigned);
15618 }
15619
15620 key = "_ArrayData_";
15621 if (value.at(key).size() != len)
15622 {
15623 return true;
15624 }
15625
15626 oa->write_character('[');
15627 oa->write_character('$');
15628 oa->write_character(dtype);
15629 oa->write_character('#');
15630
15631 key = "_ArraySize_";
15632 write_ubjson(value.at(key), use_count, use_type, true, true);
15633
15634 key = "_ArrayData_";
15635 if (dtype == 'U' || dtype == 'C')
15636 {
15637 for (const auto& el : value.at(key))
15638 {
15639 write_number(static_cast<std::uint8_t>(el.m_value.number_unsigned), true);
15640 }
15641 }
15642 else if (dtype == 'i')
15643 {
15644 for (const auto& el : value.at(key))
15645 {
15646 write_number(static_cast<std::int8_t>(el.m_value.number_integer), true);
15647 }
15648 }
15649 else if (dtype == 'u')
15650 {
15651 for (const auto& el : value.at(key))
15652 {
15653 write_number(static_cast<std::uint16_t>(el.m_value.number_unsigned), true);
15654 }
15655 }
15656 else if (dtype == 'I')
15657 {
15658 for (const auto& el : value.at(key))
15659 {
15660 write_number(static_cast<std::int16_t>(el.m_value.number_integer), true);
15661 }
15662 }
15663 else if (dtype == 'm')
15664 {
15665 for (const auto& el : value.at(key))
15666 {
15667 write_number(static_cast<std::uint32_t>(el.m_value.number_unsigned), true);
15668 }
15669 }
15670 else if (dtype == 'l')
15671 {
15672 for (const auto& el : value.at(key))
15673 {
15674 write_number(static_cast<std::int32_t>(el.m_value.number_integer), true);
15675 }
15676 }
15677 else if (dtype == 'M')
15678 {
15679 for (const auto& el : value.at(key))
15680 {
15681 write_number(static_cast<std::uint64_t>(el.m_value.number_unsigned), true);
15682 }
15683 }
15684 else if (dtype == 'L')
15685 {
15686 for (const auto& el : value.at(key))
15687 {
15688 write_number(static_cast<std::int64_t>(el.m_value.number_integer), true);
15689 }
15690 }
15691 else if (dtype == 'd')
15692 {
15693 for (const auto& el : value.at(key))
15694 {
15695 write_number(static_cast<float>(el.m_value.number_float), true);
15696 }
15697 }
15698 else if (dtype == 'D')
15699 {
15700 for (const auto& el : value.at(key))
15701 {
15702 write_number(static_cast<double>(el.m_value.number_float), true);
15703 }
15704 }
15705 return false;
15706 }
15707
15709 // Utility functions //
15711
15712 /*
15713 @brief write a number to output input
15714 @param[in] n number of type @a NumberType
15715 @param[in] OutputIsLittleEndian Set to true if output data is
15716 required to be little endian
15717 @tparam NumberType the type of the number
15718
15719 @note This function needs to respect the system's endianness, because bytes
15720 in CBOR, MessagePack, and UBJSON are stored in network order (big
15721 endian) and therefore need reordering on little endian systems.
15722 On the other hand, BSON and BJData use little endian and should reorder
15723 on big endian systems.
15724 */
15725 template<typename NumberType>
15726 void write_number(const NumberType n, const bool OutputIsLittleEndian = false)
15727 {
15728 // step 1: write number to array of length NumberType
15729 std::array<CharType, sizeof(NumberType)> vec{};
15730 std::memcpy(vec.data(), &n, sizeof(NumberType));
15731
15732 // step 2: write array to output (with possible reordering)
15733 if (is_little_endian != OutputIsLittleEndian)
15734 {
15735 // reverse byte order prior to conversion if necessary
15736 std::reverse(vec.begin(), vec.end());
15737 }
15738
15739 oa->write_characters(vec.data(), sizeof(NumberType));
15740 }
15741
15742 void write_compact_float(const number_float_t n, detail::input_format_t format)
15743 {
15744#ifdef __GNUC__
15745#pragma GCC diagnostic push
15746#pragma GCC diagnostic ignored "-Wfloat-equal"
15747#endif
15748 if (static_cast<double>(n) >= static_cast<double>(std::numeric_limits<float>::lowest()) &&
15749 static_cast<double>(n) <= static_cast<double>((std::numeric_limits<float>::max)()) &&
15750 static_cast<double>(static_cast<float>(n)) == static_cast<double>(n))
15751 {
15752 oa->write_character(format == detail::input_format_t::cbor
15753 ? get_cbor_float_prefix(static_cast<float>(n))
15754 : get_msgpack_float_prefix(static_cast<float>(n)));
15755 write_number(static_cast<float>(n));
15756 }
15757 else
15758 {
15759 oa->write_character(format == detail::input_format_t::cbor
15760 ? get_cbor_float_prefix(n)
15761 : get_msgpack_float_prefix(n));
15762 write_number(n);
15763 }
15764#ifdef __GNUC__
15765#pragma GCC diagnostic pop
15766#endif
15767 }
15768
15769 public:
15770 // The following to_char_type functions are implement the conversion
15771 // between uint8_t and CharType. In case CharType is not unsigned,
15772 // such a conversion is required to allow values greater than 128.
15773 // See <https://github.com/nlohmann/json/issues/1286> for a discussion.
15774 template < typename C = CharType,
15775 enable_if_t < std::is_signed<C>::value && std::is_signed<char>::value > * = nullptr >
15776 static constexpr CharType to_char_type(std::uint8_t x) noexcept
15777 {
15778 return *reinterpret_cast<char*>(&x);
15779 }
15780
15781 template < typename C = CharType,
15782 enable_if_t < std::is_signed<C>::value && std::is_unsigned<char>::value > * = nullptr >
15783 static CharType to_char_type(std::uint8_t x) noexcept
15784 {
15785 static_assert(sizeof(std::uint8_t) == sizeof(CharType), "size of CharType must be equal to std::uint8_t");
15786 static_assert(std::is_trivial<CharType>::value, "CharType must be trivial");
15787 CharType result;
15788 std::memcpy(&result, &x, sizeof(x));
15789 return result;
15790 }
15791
15792 template<typename C = CharType,
15793 enable_if_t<std::is_unsigned<C>::value>* = nullptr>
15794 static constexpr CharType to_char_type(std::uint8_t x) noexcept
15795 {
15796 return x;
15797 }
15798
15799 template < typename InputCharType, typename C = CharType,
15800 enable_if_t <
15801 std::is_signed<C>::value &&
15802 std::is_signed<char>::value &&
15803 std::is_same<char, typename std::remove_cv<InputCharType>::type>::value
15804 > * = nullptr >
15805 static constexpr CharType to_char_type(InputCharType x) noexcept
15806 {
15807 return x;
15808 }
15809
15810 private:
15812 const bool is_little_endian = little_endianness();
15813
15815 output_adapter_t<CharType> oa = nullptr;
15816};
15817} // namespace detail
15818} // namespace nlohmann
15819
15820// #include <nlohmann/detail/output/output_adapters.hpp>
15821
15822// #include <nlohmann/detail/output/serializer.hpp>
15823
15824
15825#include <algorithm> // reverse, remove, fill, find, none_of
15826#include <array> // array
15827#include <clocale> // localeconv, lconv
15828#include <cmath> // labs, isfinite, isnan, signbit
15829#include <cstddef> // size_t, ptrdiff_t
15830#include <cstdint> // uint8_t
15831#include <cstdio> // snprintf
15832#include <limits> // numeric_limits
15833#include <string> // string, char_traits
15834#include <iomanip> // setfill, setw
15835#include <type_traits> // is_same
15836#include <utility> // move
15837
15838// #include <nlohmann/detail/conversions/to_chars.hpp>
15839
15840
15841#include <array> // array
15842#include <cmath> // signbit, isfinite
15843#include <cstdint> // intN_t, uintN_t
15844#include <cstring> // memcpy, memmove
15845#include <limits> // numeric_limits
15846#include <type_traits> // conditional
15847
15848// #include <nlohmann/detail/macro_scope.hpp>
15849
15850
15851namespace nlohmann
15852{
15853namespace detail
15854{
15855
15875namespace dtoa_impl
15876{
15877
15878template<typename Target, typename Source>
15879Target reinterpret_bits(const Source source)
15880{
15881 static_assert(sizeof(Target) == sizeof(Source), "size mismatch");
15882
15883 Target target;
15884 std::memcpy(&target, &source, sizeof(Source));
15885 return target;
15886}
15887
15888struct diyfp // f * 2^e
15889{
15890 static constexpr int kPrecision = 64; // = q
15891
15892 std::uint64_t f = 0;
15893 int e = 0;
15894
15895 constexpr diyfp(std::uint64_t f_, int e_) noexcept : f(f_), e(e_) {}
15896
15901 static diyfp sub(const diyfp& x, const diyfp& y) noexcept
15902 {
15903 JSON_ASSERT(x.e == y.e);
15904 JSON_ASSERT(x.f >= y.f);
15905
15906 return {x.f - y.f, x.e};
15907 }
15908
15913 static diyfp mul(const diyfp& x, const diyfp& y) noexcept
15914 {
15915 static_assert(kPrecision == 64, "internal error");
15916
15917 // Computes:
15918 // f = round((x.f * y.f) / 2^q)
15919 // e = x.e + y.e + q
15920
15921 // Emulate the 64-bit * 64-bit multiplication:
15922 //
15923 // p = u * v
15924 // = (u_lo + 2^32 u_hi) (v_lo + 2^32 v_hi)
15925 // = (u_lo v_lo ) + 2^32 ((u_lo v_hi ) + (u_hi v_lo )) + 2^64 (u_hi v_hi )
15926 // = (p0 ) + 2^32 ((p1 ) + (p2 )) + 2^64 (p3 )
15927 // = (p0_lo + 2^32 p0_hi) + 2^32 ((p1_lo + 2^32 p1_hi) + (p2_lo + 2^32 p2_hi)) + 2^64 (p3 )
15928 // = (p0_lo ) + 2^32 (p0_hi + p1_lo + p2_lo ) + 2^64 (p1_hi + p2_hi + p3)
15929 // = (p0_lo ) + 2^32 (Q ) + 2^64 (H )
15930 // = (p0_lo ) + 2^32 (Q_lo + 2^32 Q_hi ) + 2^64 (H )
15931 //
15932 // (Since Q might be larger than 2^32 - 1)
15933 //
15934 // = (p0_lo + 2^32 Q_lo) + 2^64 (Q_hi + H)
15935 //
15936 // (Q_hi + H does not overflow a 64-bit int)
15937 //
15938 // = p_lo + 2^64 p_hi
15939
15940 const std::uint64_t u_lo = x.f & 0xFFFFFFFFu;
15941 const std::uint64_t u_hi = x.f >> 32u;
15942 const std::uint64_t v_lo = y.f & 0xFFFFFFFFu;
15943 const std::uint64_t v_hi = y.f >> 32u;
15944
15945 const std::uint64_t p0 = u_lo * v_lo;
15946 const std::uint64_t p1 = u_lo * v_hi;
15947 const std::uint64_t p2 = u_hi * v_lo;
15948 const std::uint64_t p3 = u_hi * v_hi;
15949
15950 const std::uint64_t p0_hi = p0 >> 32u;
15951 const std::uint64_t p1_lo = p1 & 0xFFFFFFFFu;
15952 const std::uint64_t p1_hi = p1 >> 32u;
15953 const std::uint64_t p2_lo = p2 & 0xFFFFFFFFu;
15954 const std::uint64_t p2_hi = p2 >> 32u;
15955
15956 std::uint64_t Q = p0_hi + p1_lo + p2_lo;
15957
15958 // The full product might now be computed as
15959 //
15960 // p_hi = p3 + p2_hi + p1_hi + (Q >> 32)
15961 // p_lo = p0_lo + (Q << 32)
15962 //
15963 // But in this particular case here, the full p_lo is not required.
15964 // Effectively we only need to add the highest bit in p_lo to p_hi (and
15965 // Q_hi + 1 does not overflow).
15966
15967 Q += std::uint64_t{1} << (64u - 32u - 1u); // round, ties up
15968
15969 const std::uint64_t h = p3 + p2_hi + p1_hi + (Q >> 32u);
15970
15971 return {h, x.e + y.e + 64};
15972 }
15973
15978 static diyfp normalize(diyfp x) noexcept
15979 {
15980 JSON_ASSERT(x.f != 0);
15981
15982 while ((x.f >> 63u) == 0)
15983 {
15984 x.f <<= 1u;
15985 x.e--;
15986 }
15987
15988 return x;
15989 }
15990
15995 static diyfp normalize_to(const diyfp& x, const int target_exponent) noexcept
15996 {
15997 const int delta = x.e - target_exponent;
15998
15999 JSON_ASSERT(delta >= 0);
16000 JSON_ASSERT(((x.f << delta) >> delta) == x.f);
16001
16002 return {x.f << delta, target_exponent};
16003 }
16004};
16005
16006struct boundaries
16007{
16008 diyfp w;
16009 diyfp minus;
16010 diyfp plus;
16011};
16012
16019template<typename FloatType>
16020boundaries compute_boundaries(FloatType value)
16021{
16022 JSON_ASSERT(std::isfinite(value));
16023 JSON_ASSERT(value > 0);
16024
16025 // Convert the IEEE representation into a diyfp.
16026 //
16027 // If v is denormal:
16028 // value = 0.F * 2^(1 - bias) = ( F) * 2^(1 - bias - (p-1))
16029 // If v is normalized:
16030 // value = 1.F * 2^(E - bias) = (2^(p-1) + F) * 2^(E - bias - (p-1))
16031
16032 static_assert(std::numeric_limits<FloatType>::is_iec559,
16033 "internal error: dtoa_short requires an IEEE-754 floating-point implementation");
16034
16035 constexpr int kPrecision = std::numeric_limits<FloatType>::digits; // = p (includes the hidden bit)
16036 constexpr int kBias = std::numeric_limits<FloatType>::max_exponent - 1 + (kPrecision - 1);
16037 constexpr int kMinExp = 1 - kBias;
16038 constexpr std::uint64_t kHiddenBit = std::uint64_t{1} << (kPrecision - 1); // = 2^(p-1)
16039
16040 using bits_type = typename std::conditional<kPrecision == 24, std::uint32_t, std::uint64_t >::type;
16041
16042 const auto bits = static_cast<std::uint64_t>(reinterpret_bits<bits_type>(value));
16043 const std::uint64_t E = bits >> (kPrecision - 1);
16044 const std::uint64_t F = bits & (kHiddenBit - 1);
16045
16046 const bool is_denormal = E == 0;
16047 const diyfp v = is_denormal
16048 ? diyfp(F, kMinExp)
16049 : diyfp(F + kHiddenBit, static_cast<int>(E) - kBias);
16050
16051 // Compute the boundaries m- and m+ of the floating-point value
16052 // v = f * 2^e.
16053 //
16054 // Determine v- and v+, the floating-point predecessor and successor if v,
16055 // respectively.
16056 //
16057 // v- = v - 2^e if f != 2^(p-1) or e == e_min (A)
16058 // = v - 2^(e-1) if f == 2^(p-1) and e > e_min (B)
16059 //
16060 // v+ = v + 2^e
16061 //
16062 // Let m- = (v- + v) / 2 and m+ = (v + v+) / 2. All real numbers _strictly_
16063 // between m- and m+ round to v, regardless of how the input rounding
16064 // algorithm breaks ties.
16065 //
16066 // ---+-------------+-------------+-------------+-------------+--- (A)
16067 // v- m- v m+ v+
16068 //
16069 // -----------------+------+------+-------------+-------------+--- (B)
16070 // v- m- v m+ v+
16071
16072 const bool lower_boundary_is_closer = F == 0 && E > 1;
16073 const diyfp m_plus = diyfp(2 * v.f + 1, v.e - 1);
16074 const diyfp m_minus = lower_boundary_is_closer
16075 ? diyfp(4 * v.f - 1, v.e - 2) // (B)
16076 : diyfp(2 * v.f - 1, v.e - 1); // (A)
16077
16078 // Determine the normalized w+ = m+.
16079 const diyfp w_plus = diyfp::normalize(m_plus);
16080
16081 // Determine w- = m- such that e_(w-) = e_(w+).
16082 const diyfp w_minus = diyfp::normalize_to(m_minus, w_plus.e);
16083
16084 return {diyfp::normalize(v), w_minus, w_plus};
16085}
16086
16087// Given normalized diyfp w, Grisu needs to find a (normalized) cached
16088// power-of-ten c, such that the exponent of the product c * w = f * 2^e lies
16089// within a certain range [alpha, gamma] (Definition 3.2 from [1])
16090//
16091// alpha <= e = e_c + e_w + q <= gamma
16092//
16093// or
16094//
16095// f_c * f_w * 2^alpha <= f_c 2^(e_c) * f_w 2^(e_w) * 2^q
16096// <= f_c * f_w * 2^gamma
16097//
16098// Since c and w are normalized, i.e. 2^(q-1) <= f < 2^q, this implies
16099//
16100// 2^(q-1) * 2^(q-1) * 2^alpha <= c * w * 2^q < 2^q * 2^q * 2^gamma
16101//
16102// or
16103//
16104// 2^(q - 2 + alpha) <= c * w < 2^(q + gamma)
16105//
16106// The choice of (alpha,gamma) determines the size of the table and the form of
16107// the digit generation procedure. Using (alpha,gamma)=(-60,-32) works out well
16108// in practice:
16109//
16110// The idea is to cut the number c * w = f * 2^e into two parts, which can be
16111// processed independently: An integral part p1, and a fractional part p2:
16112//
16113// f * 2^e = ( (f div 2^-e) * 2^-e + (f mod 2^-e) ) * 2^e
16114// = (f div 2^-e) + (f mod 2^-e) * 2^e
16115// = p1 + p2 * 2^e
16116//
16117// The conversion of p1 into decimal form requires a series of divisions and
16118// modulos by (a power of) 10. These operations are faster for 32-bit than for
16119// 64-bit integers, so p1 should ideally fit into a 32-bit integer. This can be
16120// achieved by choosing
16121//
16122// -e >= 32 or e <= -32 := gamma
16123//
16124// In order to convert the fractional part
16125//
16126// p2 * 2^e = p2 / 2^-e = d[-1] / 10^1 + d[-2] / 10^2 + ...
16127//
16128// into decimal form, the fraction is repeatedly multiplied by 10 and the digits
16129// d[-i] are extracted in order:
16130//
16131// (10 * p2) div 2^-e = d[-1]
16132// (10 * p2) mod 2^-e = d[-2] / 10^1 + ...
16133//
16134// The multiplication by 10 must not overflow. It is sufficient to choose
16135//
16136// 10 * p2 < 16 * p2 = 2^4 * p2 <= 2^64.
16137//
16138// Since p2 = f mod 2^-e < 2^-e,
16139//
16140// -e <= 60 or e >= -60 := alpha
16141
16142constexpr int kAlpha = -60;
16143constexpr int kGamma = -32;
16144
16145struct cached_power // c = f * 2^e ~= 10^k
16146{
16147 std::uint64_t f;
16148 int e;
16149 int k;
16150};
16151
16159inline cached_power get_cached_power_for_binary_exponent(int e)
16160{
16161 // Now
16162 //
16163 // alpha <= e_c + e + q <= gamma (1)
16164 // ==> f_c * 2^alpha <= c * 2^e * 2^q
16165 //
16166 // and since the c's are normalized, 2^(q-1) <= f_c,
16167 //
16168 // ==> 2^(q - 1 + alpha) <= c * 2^(e + q)
16169 // ==> 2^(alpha - e - 1) <= c
16170 //
16171 // If c were an exact power of ten, i.e. c = 10^k, one may determine k as
16172 //
16173 // k = ceil( log_10( 2^(alpha - e - 1) ) )
16174 // = ceil( (alpha - e - 1) * log_10(2) )
16175 //
16176 // From the paper:
16177 // "In theory the result of the procedure could be wrong since c is rounded,
16178 // and the computation itself is approximated [...]. In practice, however,
16179 // this simple function is sufficient."
16180 //
16181 // For IEEE double precision floating-point numbers converted into
16182 // normalized diyfp's w = f * 2^e, with q = 64,
16183 //
16184 // e >= -1022 (min IEEE exponent)
16185 // -52 (p - 1)
16186 // -52 (p - 1, possibly normalize denormal IEEE numbers)
16187 // -11 (normalize the diyfp)
16188 // = -1137
16189 //
16190 // and
16191 //
16192 // e <= +1023 (max IEEE exponent)
16193 // -52 (p - 1)
16194 // -11 (normalize the diyfp)
16195 // = 960
16196 //
16197 // This binary exponent range [-1137,960] results in a decimal exponent
16198 // range [-307,324]. One does not need to store a cached power for each
16199 // k in this range. For each such k it suffices to find a cached power
16200 // such that the exponent of the product lies in [alpha,gamma].
16201 // This implies that the difference of the decimal exponents of adjacent
16202 // table entries must be less than or equal to
16203 //
16204 // floor( (gamma - alpha) * log_10(2) ) = 8.
16205 //
16206 // (A smaller distance gamma-alpha would require a larger table.)
16207
16208 // NB:
16209 // Actually this function returns c, such that -60 <= e_c + e + 64 <= -34.
16210
16211 constexpr int kCachedPowersMinDecExp = -300;
16212 constexpr int kCachedPowersDecStep = 8;
16213
16214 static constexpr std::array<cached_power, 79> kCachedPowers =
16215 {
16216 {
16217 { 0xAB70FE17C79AC6CA, -1060, -300 },
16218 { 0xFF77B1FCBEBCDC4F, -1034, -292 },
16219 { 0xBE5691EF416BD60C, -1007, -284 },
16220 { 0x8DD01FAD907FFC3C, -980, -276 },
16221 { 0xD3515C2831559A83, -954, -268 },
16222 { 0x9D71AC8FADA6C9B5, -927, -260 },
16223 { 0xEA9C227723EE8BCB, -901, -252 },
16224 { 0xAECC49914078536D, -874, -244 },
16225 { 0x823C12795DB6CE57, -847, -236 },
16226 { 0xC21094364DFB5637, -821, -228 },
16227 { 0x9096EA6F3848984F, -794, -220 },
16228 { 0xD77485CB25823AC7, -768, -212 },
16229 { 0xA086CFCD97BF97F4, -741, -204 },
16230 { 0xEF340A98172AACE5, -715, -196 },
16231 { 0xB23867FB2A35B28E, -688, -188 },
16232 { 0x84C8D4DFD2C63F3B, -661, -180 },
16233 { 0xC5DD44271AD3CDBA, -635, -172 },
16234 { 0x936B9FCEBB25C996, -608, -164 },
16235 { 0xDBAC6C247D62A584, -582, -156 },
16236 { 0xA3AB66580D5FDAF6, -555, -148 },
16237 { 0xF3E2F893DEC3F126, -529, -140 },
16238 { 0xB5B5ADA8AAFF80B8, -502, -132 },
16239 { 0x87625F056C7C4A8B, -475, -124 },
16240 { 0xC9BCFF6034C13053, -449, -116 },
16241 { 0x964E858C91BA2655, -422, -108 },
16242 { 0xDFF9772470297EBD, -396, -100 },
16243 { 0xA6DFBD9FB8E5B88F, -369, -92 },
16244 { 0xF8A95FCF88747D94, -343, -84 },
16245 { 0xB94470938FA89BCF, -316, -76 },
16246 { 0x8A08F0F8BF0F156B, -289, -68 },
16247 { 0xCDB02555653131B6, -263, -60 },
16248 { 0x993FE2C6D07B7FAC, -236, -52 },
16249 { 0xE45C10C42A2B3B06, -210, -44 },
16250 { 0xAA242499697392D3, -183, -36 },
16251 { 0xFD87B5F28300CA0E, -157, -28 },
16252 { 0xBCE5086492111AEB, -130, -20 },
16253 { 0x8CBCCC096F5088CC, -103, -12 },
16254 { 0xD1B71758E219652C, -77, -4 },
16255 { 0x9C40000000000000, -50, 4 },
16256 { 0xE8D4A51000000000, -24, 12 },
16257 { 0xAD78EBC5AC620000, 3, 20 },
16258 { 0x813F3978F8940984, 30, 28 },
16259 { 0xC097CE7BC90715B3, 56, 36 },
16260 { 0x8F7E32CE7BEA5C70, 83, 44 },
16261 { 0xD5D238A4ABE98068, 109, 52 },
16262 { 0x9F4F2726179A2245, 136, 60 },
16263 { 0xED63A231D4C4FB27, 162, 68 },
16264 { 0xB0DE65388CC8ADA8, 189, 76 },
16265 { 0x83C7088E1AAB65DB, 216, 84 },
16266 { 0xC45D1DF942711D9A, 242, 92 },
16267 { 0x924D692CA61BE758, 269, 100 },
16268 { 0xDA01EE641A708DEA, 295, 108 },
16269 { 0xA26DA3999AEF774A, 322, 116 },
16270 { 0xF209787BB47D6B85, 348, 124 },
16271 { 0xB454E4A179DD1877, 375, 132 },
16272 { 0x865B86925B9BC5C2, 402, 140 },
16273 { 0xC83553C5C8965D3D, 428, 148 },
16274 { 0x952AB45CFA97A0B3, 455, 156 },
16275 { 0xDE469FBD99A05FE3, 481, 164 },
16276 { 0xA59BC234DB398C25, 508, 172 },
16277 { 0xF6C69A72A3989F5C, 534, 180 },
16278 { 0xB7DCBF5354E9BECE, 561, 188 },
16279 { 0x88FCF317F22241E2, 588, 196 },
16280 { 0xCC20CE9BD35C78A5, 614, 204 },
16281 { 0x98165AF37B2153DF, 641, 212 },
16282 { 0xE2A0B5DC971F303A, 667, 220 },
16283 { 0xA8D9D1535CE3B396, 694, 228 },
16284 { 0xFB9B7CD9A4A7443C, 720, 236 },
16285 { 0xBB764C4CA7A44410, 747, 244 },
16286 { 0x8BAB8EEFB6409C1A, 774, 252 },
16287 { 0xD01FEF10A657842C, 800, 260 },
16288 { 0x9B10A4E5E9913129, 827, 268 },
16289 { 0xE7109BFBA19C0C9D, 853, 276 },
16290 { 0xAC2820D9623BF429, 880, 284 },
16291 { 0x80444B5E7AA7CF85, 907, 292 },
16292 { 0xBF21E44003ACDD2D, 933, 300 },
16293 { 0x8E679C2F5E44FF8F, 960, 308 },
16294 { 0xD433179D9C8CB841, 986, 316 },
16295 { 0x9E19DB92B4E31BA9, 1013, 324 },
16296 }
16297 };
16298
16299 // This computation gives exactly the same results for k as
16300 // k = ceil((kAlpha - e - 1) * 0.30102999566398114)
16301 // for |e| <= 1500, but doesn't require floating-point operations.
16302 // NB: log_10(2) ~= 78913 / 2^18
16303 JSON_ASSERT(e >= -1500);
16304 JSON_ASSERT(e <= 1500);
16305 const int f = kAlpha - e - 1;
16306 const int k = (f * 78913) / (1 << 18) + static_cast<int>(f > 0);
16307
16308 const int index = (-kCachedPowersMinDecExp + k + (kCachedPowersDecStep - 1)) / kCachedPowersDecStep;
16309 JSON_ASSERT(index >= 0);
16310 JSON_ASSERT(static_cast<std::size_t>(index) < kCachedPowers.size());
16311
16312 const cached_power cached = kCachedPowers[static_cast<std::size_t>(index)];
16313 JSON_ASSERT(kAlpha <= cached.e + e + 64);
16314 JSON_ASSERT(kGamma >= cached.e + e + 64);
16315
16316 return cached;
16317}
16318
16323inline int find_largest_pow10(const std::uint32_t n, std::uint32_t& pow10)
16324{
16325 // LCOV_EXCL_START
16326 if (n >= 1000000000)
16327 {
16328 pow10 = 1000000000;
16329 return 10;
16330 }
16331 // LCOV_EXCL_STOP
16332 if (n >= 100000000)
16333 {
16334 pow10 = 100000000;
16335 return 9;
16336 }
16337 if (n >= 10000000)
16338 {
16339 pow10 = 10000000;
16340 return 8;
16341 }
16342 if (n >= 1000000)
16343 {
16344 pow10 = 1000000;
16345 return 7;
16346 }
16347 if (n >= 100000)
16348 {
16349 pow10 = 100000;
16350 return 6;
16351 }
16352 if (n >= 10000)
16353 {
16354 pow10 = 10000;
16355 return 5;
16356 }
16357 if (n >= 1000)
16358 {
16359 pow10 = 1000;
16360 return 4;
16361 }
16362 if (n >= 100)
16363 {
16364 pow10 = 100;
16365 return 3;
16366 }
16367 if (n >= 10)
16368 {
16369 pow10 = 10;
16370 return 2;
16371 }
16372
16373 pow10 = 1;
16374 return 1;
16375}
16376
16377inline void grisu2_round(char* buf, int len, std::uint64_t dist, std::uint64_t delta,
16378 std::uint64_t rest, std::uint64_t ten_k)
16379{
16380 JSON_ASSERT(len >= 1);
16381 JSON_ASSERT(dist <= delta);
16382 JSON_ASSERT(rest <= delta);
16383 JSON_ASSERT(ten_k > 0);
16384
16385 // <--------------------------- delta ---->
16386 // <---- dist --------->
16387 // --------------[------------------+-------------------]--------------
16388 // M- w M+
16389 //
16390 // ten_k
16391 // <------>
16392 // <---- rest ---->
16393 // --------------[------------------+----+--------------]--------------
16394 // w V
16395 // = buf * 10^k
16396 //
16397 // ten_k represents a unit-in-the-last-place in the decimal representation
16398 // stored in buf.
16399 // Decrement buf by ten_k while this takes buf closer to w.
16400
16401 // The tests are written in this order to avoid overflow in unsigned
16402 // integer arithmetic.
16403
16404 while (rest < dist
16405 && delta - rest >= ten_k
16406 && (rest + ten_k < dist || dist - rest > rest + ten_k - dist))
16407 {
16408 JSON_ASSERT(buf[len - 1] != '0');
16409 buf[len - 1]--;
16410 rest += ten_k;
16411 }
16412}
16413
16418inline void grisu2_digit_gen(char* buffer, int& length, int& decimal_exponent,
16419 diyfp M_minus, diyfp w, diyfp M_plus)
16420{
16421 static_assert(kAlpha >= -60, "internal error");
16422 static_assert(kGamma <= -32, "internal error");
16423
16424 // Generates the digits (and the exponent) of a decimal floating-point
16425 // number V = buffer * 10^decimal_exponent in the range [M-, M+]. The diyfp's
16426 // w, M- and M+ share the same exponent e, which satisfies alpha <= e <= gamma.
16427 //
16428 // <--------------------------- delta ---->
16429 // <---- dist --------->
16430 // --------------[------------------+-------------------]--------------
16431 // M- w M+
16432 //
16433 // Grisu2 generates the digits of M+ from left to right and stops as soon as
16434 // V is in [M-,M+].
16435
16436 JSON_ASSERT(M_plus.e >= kAlpha);
16437 JSON_ASSERT(M_plus.e <= kGamma);
16438
16439 std::uint64_t delta = diyfp::sub(M_plus, M_minus).f; // (significand of (M+ - M-), implicit exponent is e)
16440 std::uint64_t dist = diyfp::sub(M_plus, w ).f; // (significand of (M+ - w ), implicit exponent is e)
16441
16442 // Split M+ = f * 2^e into two parts p1 and p2 (note: e < 0):
16443 //
16444 // M+ = f * 2^e
16445 // = ((f div 2^-e) * 2^-e + (f mod 2^-e)) * 2^e
16446 // = ((p1 ) * 2^-e + (p2 )) * 2^e
16447 // = p1 + p2 * 2^e
16448
16449 const diyfp one(std::uint64_t{1} << -M_plus.e, M_plus.e);
16450
16451 auto p1 = static_cast<std::uint32_t>(M_plus.f >> -one.e); // p1 = f div 2^-e (Since -e >= 32, p1 fits into a 32-bit int.)
16452 std::uint64_t p2 = M_plus.f & (one.f - 1); // p2 = f mod 2^-e
16453
16454 // 1)
16455 //
16456 // Generate the digits of the integral part p1 = d[n-1]...d[1]d[0]
16457
16458 JSON_ASSERT(p1 > 0);
16459
16460 std::uint32_t pow10{};
16461 const int k = find_largest_pow10(p1, pow10);
16462
16463 // 10^(k-1) <= p1 < 10^k, pow10 = 10^(k-1)
16464 //
16465 // p1 = (p1 div 10^(k-1)) * 10^(k-1) + (p1 mod 10^(k-1))
16466 // = (d[k-1] ) * 10^(k-1) + (p1 mod 10^(k-1))
16467 //
16468 // M+ = p1 + p2 * 2^e
16469 // = d[k-1] * 10^(k-1) + (p1 mod 10^(k-1)) + p2 * 2^e
16470 // = d[k-1] * 10^(k-1) + ((p1 mod 10^(k-1)) * 2^-e + p2) * 2^e
16471 // = d[k-1] * 10^(k-1) + ( rest) * 2^e
16472 //
16473 // Now generate the digits d[n] of p1 from left to right (n = k-1,...,0)
16474 //
16475 // p1 = d[k-1]...d[n] * 10^n + d[n-1]...d[0]
16476 //
16477 // but stop as soon as
16478 //
16479 // rest * 2^e = (d[n-1]...d[0] * 2^-e + p2) * 2^e <= delta * 2^e
16480
16481 int n = k;
16482 while (n > 0)
16483 {
16484 // Invariants:
16485 // M+ = buffer * 10^n + (p1 + p2 * 2^e) (buffer = 0 for n = k)
16486 // pow10 = 10^(n-1) <= p1 < 10^n
16487 //
16488 const std::uint32_t d = p1 / pow10; // d = p1 div 10^(n-1)
16489 const std::uint32_t r = p1 % pow10; // r = p1 mod 10^(n-1)
16490 //
16491 // M+ = buffer * 10^n + (d * 10^(n-1) + r) + p2 * 2^e
16492 // = (buffer * 10 + d) * 10^(n-1) + (r + p2 * 2^e)
16493 //
16494 JSON_ASSERT(d <= 9);
16495 buffer[length++] = static_cast<char>('0' + d); // buffer := buffer * 10 + d
16496 //
16497 // M+ = buffer * 10^(n-1) + (r + p2 * 2^e)
16498 //
16499 p1 = r;
16500 n--;
16501 //
16502 // M+ = buffer * 10^n + (p1 + p2 * 2^e)
16503 // pow10 = 10^n
16504 //
16505
16506 // Now check if enough digits have been generated.
16507 // Compute
16508 //
16509 // p1 + p2 * 2^e = (p1 * 2^-e + p2) * 2^e = rest * 2^e
16510 //
16511 // Note:
16512 // Since rest and delta share the same exponent e, it suffices to
16513 // compare the significands.
16514 const std::uint64_t rest = (std::uint64_t{p1} << -one.e) + p2;
16515 if (rest <= delta)
16516 {
16517 // V = buffer * 10^n, with M- <= V <= M+.
16518
16519 decimal_exponent += n;
16520
16521 // We may now just stop. But instead look if the buffer could be
16522 // decremented to bring V closer to w.
16523 //
16524 // pow10 = 10^n is now 1 ulp in the decimal representation V.
16525 // The rounding procedure works with diyfp's with an implicit
16526 // exponent of e.
16527 //
16528 // 10^n = (10^n * 2^-e) * 2^e = ulp * 2^e
16529 //
16530 const std::uint64_t ten_n = std::uint64_t{pow10} << -one.e;
16531 grisu2_round(buffer, length, dist, delta, rest, ten_n);
16532
16533 return;
16534 }
16535
16536 pow10 /= 10;
16537 //
16538 // pow10 = 10^(n-1) <= p1 < 10^n
16539 // Invariants restored.
16540 }
16541
16542 // 2)
16543 //
16544 // The digits of the integral part have been generated:
16545 //
16546 // M+ = d[k-1]...d[1]d[0] + p2 * 2^e
16547 // = buffer + p2 * 2^e
16548 //
16549 // Now generate the digits of the fractional part p2 * 2^e.
16550 //
16551 // Note:
16552 // No decimal point is generated: the exponent is adjusted instead.
16553 //
16554 // p2 actually represents the fraction
16555 //
16556 // p2 * 2^e
16557 // = p2 / 2^-e
16558 // = d[-1] / 10^1 + d[-2] / 10^2 + ...
16559 //
16560 // Now generate the digits d[-m] of p1 from left to right (m = 1,2,...)
16561 //
16562 // p2 * 2^e = d[-1]d[-2]...d[-m] * 10^-m
16563 // + 10^-m * (d[-m-1] / 10^1 + d[-m-2] / 10^2 + ...)
16564 //
16565 // using
16566 //
16567 // 10^m * p2 = ((10^m * p2) div 2^-e) * 2^-e + ((10^m * p2) mod 2^-e)
16568 // = ( d) * 2^-e + ( r)
16569 //
16570 // or
16571 // 10^m * p2 * 2^e = d + r * 2^e
16572 //
16573 // i.e.
16574 //
16575 // M+ = buffer + p2 * 2^e
16576 // = buffer + 10^-m * (d + r * 2^e)
16577 // = (buffer * 10^m + d) * 10^-m + 10^-m * r * 2^e
16578 //
16579 // and stop as soon as 10^-m * r * 2^e <= delta * 2^e
16580
16581 JSON_ASSERT(p2 > delta);
16582
16583 int m = 0;
16584 for (;;)
16585 {
16586 // Invariant:
16587 // M+ = buffer * 10^-m + 10^-m * (d[-m-1] / 10 + d[-m-2] / 10^2 + ...) * 2^e
16588 // = buffer * 10^-m + 10^-m * (p2 ) * 2^e
16589 // = buffer * 10^-m + 10^-m * (1/10 * (10 * p2) ) * 2^e
16590 // = buffer * 10^-m + 10^-m * (1/10 * ((10*p2 div 2^-e) * 2^-e + (10*p2 mod 2^-e)) * 2^e
16591 //
16592 JSON_ASSERT(p2 <= (std::numeric_limits<std::uint64_t>::max)() / 10);
16593 p2 *= 10;
16594 const std::uint64_t d = p2 >> -one.e; // d = (10 * p2) div 2^-e
16595 const std::uint64_t r = p2 & (one.f - 1); // r = (10 * p2) mod 2^-e
16596 //
16597 // M+ = buffer * 10^-m + 10^-m * (1/10 * (d * 2^-e + r) * 2^e
16598 // = buffer * 10^-m + 10^-m * (1/10 * (d + r * 2^e))
16599 // = (buffer * 10 + d) * 10^(-m-1) + 10^(-m-1) * r * 2^e
16600 //
16601 JSON_ASSERT(d <= 9);
16602 buffer[length++] = static_cast<char>('0' + d); // buffer := buffer * 10 + d
16603 //
16604 // M+ = buffer * 10^(-m-1) + 10^(-m-1) * r * 2^e
16605 //
16606 p2 = r;
16607 m++;
16608 //
16609 // M+ = buffer * 10^-m + 10^-m * p2 * 2^e
16610 // Invariant restored.
16611
16612 // Check if enough digits have been generated.
16613 //
16614 // 10^-m * p2 * 2^e <= delta * 2^e
16615 // p2 * 2^e <= 10^m * delta * 2^e
16616 // p2 <= 10^m * delta
16617 delta *= 10;
16618 dist *= 10;
16619 if (p2 <= delta)
16620 {
16621 break;
16622 }
16623 }
16624
16625 // V = buffer * 10^-m, with M- <= V <= M+.
16626
16627 decimal_exponent -= m;
16628
16629 // 1 ulp in the decimal representation is now 10^-m.
16630 // Since delta and dist are now scaled by 10^m, we need to do the
16631 // same with ulp in order to keep the units in sync.
16632 //
16633 // 10^m * 10^-m = 1 = 2^-e * 2^e = ten_m * 2^e
16634 //
16635 const std::uint64_t ten_m = one.f;
16636 grisu2_round(buffer, length, dist, delta, p2, ten_m);
16637
16638 // By construction this algorithm generates the shortest possible decimal
16639 // number (Loitsch, Theorem 6.2) which rounds back to w.
16640 // For an input number of precision p, at least
16641 //
16642 // N = 1 + ceil(p * log_10(2))
16643 //
16644 // decimal digits are sufficient to identify all binary floating-point
16645 // numbers (Matula, "In-and-Out conversions").
16646 // This implies that the algorithm does not produce more than N decimal
16647 // digits.
16648 //
16649 // N = 17 for p = 53 (IEEE double precision)
16650 // N = 9 for p = 24 (IEEE single precision)
16651}
16652
16659inline void grisu2(char* buf, int& len, int& decimal_exponent,
16660 diyfp m_minus, diyfp v, diyfp m_plus)
16661{
16662 JSON_ASSERT(m_plus.e == m_minus.e);
16663 JSON_ASSERT(m_plus.e == v.e);
16664
16665 // --------(-----------------------+-----------------------)-------- (A)
16666 // m- v m+
16667 //
16668 // --------------------(-----------+-----------------------)-------- (B)
16669 // m- v m+
16670 //
16671 // First scale v (and m- and m+) such that the exponent is in the range
16672 // [alpha, gamma].
16673
16674 const cached_power cached = get_cached_power_for_binary_exponent(m_plus.e);
16675
16676 const diyfp c_minus_k(cached.f, cached.e); // = c ~= 10^-k
16677
16678 // The exponent of the products is = v.e + c_minus_k.e + q and is in the range [alpha,gamma]
16679 const diyfp w = diyfp::mul(v, c_minus_k);
16680 const diyfp w_minus = diyfp::mul(m_minus, c_minus_k);
16681 const diyfp w_plus = diyfp::mul(m_plus, c_minus_k);
16682
16683 // ----(---+---)---------------(---+---)---------------(---+---)----
16684 // w- w w+
16685 // = c*m- = c*v = c*m+
16686 //
16687 // diyfp::mul rounds its result and c_minus_k is approximated too. w, w- and
16688 // w+ are now off by a small amount.
16689 // In fact:
16690 //
16691 // w - v * 10^k < 1 ulp
16692 //
16693 // To account for this inaccuracy, add resp. subtract 1 ulp.
16694 //
16695 // --------+---[---------------(---+---)---------------]---+--------
16696 // w- M- w M+ w+
16697 //
16698 // Now any number in [M-, M+] (bounds included) will round to w when input,
16699 // regardless of how the input rounding algorithm breaks ties.
16700 //
16701 // And digit_gen generates the shortest possible such number in [M-, M+].
16702 // Note that this does not mean that Grisu2 always generates the shortest
16703 // possible number in the interval (m-, m+).
16704 const diyfp M_minus(w_minus.f + 1, w_minus.e);
16705 const diyfp M_plus (w_plus.f - 1, w_plus.e );
16706
16707 decimal_exponent = -cached.k; // = -(-k) = k
16708
16709 grisu2_digit_gen(buf, len, decimal_exponent, M_minus, w, M_plus);
16710}
16711
16717template<typename FloatType>
16719void grisu2(char* buf, int& len, int& decimal_exponent, FloatType value)
16720{
16721 static_assert(diyfp::kPrecision >= std::numeric_limits<FloatType>::digits + 3,
16722 "internal error: not enough precision");
16723
16724 JSON_ASSERT(std::isfinite(value));
16725 JSON_ASSERT(value > 0);
16726
16727 // If the neighbors (and boundaries) of 'value' are always computed for double-precision
16728 // numbers, all float's can be recovered using strtod (and strtof). However, the resulting
16729 // decimal representations are not exactly "short".
16730 //
16731 // The documentation for 'std::to_chars' (https://en.cppreference.com/w/cpp/utility/to_chars)
16732 // says "value is converted to a string as if by std::sprintf in the default ("C") locale"
16733 // and since sprintf promotes floats to doubles, I think this is exactly what 'std::to_chars'
16734 // does.
16735 // On the other hand, the documentation for 'std::to_chars' requires that "parsing the
16736 // representation using the corresponding std::from_chars function recovers value exactly". That
16737 // indicates that single precision floating-point numbers should be recovered using
16738 // 'std::strtof'.
16739 //
16740 // NB: If the neighbors are computed for single-precision numbers, there is a single float
16741 // (7.0385307e-26f) which can't be recovered using strtod. The resulting double precision
16742 // value is off by 1 ulp.
16743#if 0
16744 const boundaries w = compute_boundaries(static_cast<double>(value));
16745#else
16746 const boundaries w = compute_boundaries(value);
16747#endif
16748
16749 grisu2(buf, len, decimal_exponent, w.minus, w.w, w.plus);
16750}
16751
16759inline char* append_exponent(char* buf, int e)
16760{
16761 JSON_ASSERT(e > -1000);
16762 JSON_ASSERT(e < 1000);
16763
16764 if (e < 0)
16765 {
16766 e = -e;
16767 *buf++ = '-';
16768 }
16769 else
16770 {
16771 *buf++ = '+';
16772 }
16773
16774 auto k = static_cast<std::uint32_t>(e);
16775 if (k < 10)
16776 {
16777 // Always print at least two digits in the exponent.
16778 // This is for compatibility with printf("%g").
16779 *buf++ = '0';
16780 *buf++ = static_cast<char>('0' + k);
16781 }
16782 else if (k < 100)
16783 {
16784 *buf++ = static_cast<char>('0' + k / 10);
16785 k %= 10;
16786 *buf++ = static_cast<char>('0' + k);
16787 }
16788 else
16789 {
16790 *buf++ = static_cast<char>('0' + k / 100);
16791 k %= 100;
16792 *buf++ = static_cast<char>('0' + k / 10);
16793 k %= 10;
16794 *buf++ = static_cast<char>('0' + k);
16795 }
16796
16797 return buf;
16798}
16799
16811inline char* format_buffer(char* buf, int len, int decimal_exponent,
16812 int min_exp, int max_exp)
16813{
16814 JSON_ASSERT(min_exp < 0);
16815 JSON_ASSERT(max_exp > 0);
16816
16817 const int k = len;
16818 const int n = len + decimal_exponent;
16819
16820 // v = buf * 10^(n-k)
16821 // k is the length of the buffer (number of decimal digits)
16822 // n is the position of the decimal point relative to the start of the buffer.
16823
16824 if (k <= n && n <= max_exp)
16825 {
16826 // digits[000]
16827 // len <= max_exp + 2
16828
16829 std::memset(buf + k, '0', static_cast<size_t>(n) - static_cast<size_t>(k));
16830 // Make it look like a floating-point number (#362, #378)
16831 buf[n + 0] = '.';
16832 buf[n + 1] = '0';
16833 return buf + (static_cast<size_t>(n) + 2);
16834 }
16835
16836 if (0 < n && n <= max_exp)
16837 {
16838 // dig.its
16839 // len <= max_digits10 + 1
16840
16841 JSON_ASSERT(k > n);
16842
16843 std::memmove(buf + (static_cast<size_t>(n) + 1), buf + n, static_cast<size_t>(k) - static_cast<size_t>(n));
16844 buf[n] = '.';
16845 return buf + (static_cast<size_t>(k) + 1U);
16846 }
16847
16848 if (min_exp < n && n <= 0)
16849 {
16850 // 0.[000]digits
16851 // len <= 2 + (-min_exp - 1) + max_digits10
16852
16853 std::memmove(buf + (2 + static_cast<size_t>(-n)), buf, static_cast<size_t>(k));
16854 buf[0] = '0';
16855 buf[1] = '.';
16856 std::memset(buf + 2, '0', static_cast<size_t>(-n));
16857 return buf + (2U + static_cast<size_t>(-n) + static_cast<size_t>(k));
16858 }
16859
16860 if (k == 1)
16861 {
16862 // dE+123
16863 // len <= 1 + 5
16864
16865 buf += 1;
16866 }
16867 else
16868 {
16869 // d.igitsE+123
16870 // len <= max_digits10 + 1 + 5
16871
16872 std::memmove(buf + 2, buf + 1, static_cast<size_t>(k) - 1);
16873 buf[1] = '.';
16874 buf += 1 + static_cast<size_t>(k);
16875 }
16876
16877 *buf++ = 'e';
16878 return append_exponent(buf, n - 1);
16879}
16880
16881} // namespace dtoa_impl
16882
16893template<typename FloatType>
16896char* to_chars(char* first, const char* last, FloatType value)
16897{
16898 static_cast<void>(last); // maybe unused - fix warning
16899 JSON_ASSERT(std::isfinite(value));
16900
16901 // Use signbit(value) instead of (value < 0) since signbit works for -0.
16902 if (std::signbit(value))
16903 {
16904 value = -value;
16905 *first++ = '-';
16906 }
16907
16908#ifdef __GNUC__
16909#pragma GCC diagnostic push
16910#pragma GCC diagnostic ignored "-Wfloat-equal"
16911#endif
16912 if (value == 0) // +-0
16913 {
16914 *first++ = '0';
16915 // Make it look like a floating-point number (#362, #378)
16916 *first++ = '.';
16917 *first++ = '0';
16918 return first;
16919 }
16920#ifdef __GNUC__
16921#pragma GCC diagnostic pop
16922#endif
16923
16924 JSON_ASSERT(last - first >= std::numeric_limits<FloatType>::max_digits10);
16925
16926 // Compute v = buffer * 10^decimal_exponent.
16927 // The decimal digits are stored in the buffer, which needs to be interpreted
16928 // as an unsigned decimal integer.
16929 // len is the length of the buffer, i.e. the number of decimal digits.
16930 int len = 0;
16931 int decimal_exponent = 0;
16932 dtoa_impl::grisu2(first, len, decimal_exponent, value);
16933
16934 JSON_ASSERT(len <= std::numeric_limits<FloatType>::max_digits10);
16935
16936 // Format the buffer like printf("%.*g", prec, value)
16937 constexpr int kMinExp = -4;
16938 // Use digits10 here to increase compatibility with version 2.
16939 constexpr int kMaxExp = std::numeric_limits<FloatType>::digits10;
16940
16941 JSON_ASSERT(last - first >= kMaxExp + 2);
16942 JSON_ASSERT(last - first >= 2 + (-kMinExp - 1) + std::numeric_limits<FloatType>::max_digits10);
16943 JSON_ASSERT(last - first >= std::numeric_limits<FloatType>::max_digits10 + 6);
16944
16945 return dtoa_impl::format_buffer(first, len, decimal_exponent, kMinExp, kMaxExp);
16946}
16947
16948} // namespace detail
16949} // namespace nlohmann
16950
16951// #include <nlohmann/detail/exceptions.hpp>
16952
16953// #include <nlohmann/detail/macro_scope.hpp>
16954
16955// #include <nlohmann/detail/meta/cpp_future.hpp>
16956
16957// #include <nlohmann/detail/output/binary_writer.hpp>
16958
16959// #include <nlohmann/detail/output/output_adapters.hpp>
16960
16961// #include <nlohmann/detail/string_concat.hpp>
16962
16963// #include <nlohmann/detail/value_t.hpp>
16964
16965
16966namespace nlohmann
16967{
16968namespace detail
16969{
16971// serialization //
16973
16976{
16977 strict,
16978 replace,
16979 ignore
16980};
16981
16982template<typename BasicJsonType>
16984{
16985 using string_t = typename BasicJsonType::string_t;
16986 using number_float_t = typename BasicJsonType::number_float_t;
16987 using number_integer_t = typename BasicJsonType::number_integer_t;
16988 using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
16989 using binary_char_t = typename BasicJsonType::binary_t::value_type;
16990 static constexpr std::uint8_t UTF8_ACCEPT = 0;
16991 static constexpr std::uint8_t UTF8_REJECT = 1;
16992
16993 public:
16999 serializer(output_adapter_t<char> s, const char ichar,
17001 : o(std::move(s))
17002 , loc(std::localeconv())
17003 , thousands_sep(loc->thousands_sep == nullptr ? '\0' : std::char_traits<char>::to_char_type(* (loc->thousands_sep)))
17004 , decimal_point(loc->decimal_point == nullptr ? '\0' : std::char_traits<char>::to_char_type(* (loc->decimal_point)))
17005 , indent_char(ichar)
17007 , error_handler(error_handler_)
17008 {}
17009
17010 // delete because of pointer members
17011 serializer(const serializer&) = delete;
17015 ~serializer() = default;
17016
17039 void dump(const BasicJsonType& val,
17040 const bool pretty_print,
17041 const bool ensure_ascii,
17042 const unsigned int indent_step,
17043 const unsigned int current_indent = 0)
17044 {
17045 switch (val.m_type)
17046 {
17047 case value_t::object:
17048 {
17049 if (val.m_value.object->empty())
17050 {
17051 o->write_characters("{}", 2);
17052 return;
17053 }
17054
17055 if (pretty_print)
17056 {
17057 o->write_characters("{\n", 2);
17058
17059 // variable to hold indentation for recursive calls
17060 const auto new_indent = current_indent + indent_step;
17061 if (JSON_HEDLEY_UNLIKELY(indent_string.size() < new_indent))
17062 {
17063 indent_string.resize(indent_string.size() * 2, ' ');
17064 }
17065
17066 // first n-1 elements
17067 auto i = val.m_value.object->cbegin();
17068 for (std::size_t cnt = 0; cnt < val.m_value.object->size() - 1; ++cnt, ++i)
17069 {
17070 o->write_characters(indent_string.c_str(), new_indent);
17071 o->write_character('\"');
17072 dump_escaped(i->first, ensure_ascii);
17073 o->write_characters("\": ", 3);
17074 dump(i->second, true, ensure_ascii, indent_step, new_indent);
17075 o->write_characters(",\n", 2);
17076 }
17077
17078 // last element
17079 JSON_ASSERT(i != val.m_value.object->cend());
17080 JSON_ASSERT(std::next(i) == val.m_value.object->cend());
17081 o->write_characters(indent_string.c_str(), new_indent);
17082 o->write_character('\"');
17083 dump_escaped(i->first, ensure_ascii);
17084 o->write_characters("\": ", 3);
17085 dump(i->second, true, ensure_ascii, indent_step, new_indent);
17086
17087 o->write_character('\n');
17088 o->write_characters(indent_string.c_str(), current_indent);
17089 o->write_character('}');
17090 }
17091 else
17092 {
17093 o->write_character('{');
17094
17095 // first n-1 elements
17096 auto i = val.m_value.object->cbegin();
17097 for (std::size_t cnt = 0; cnt < val.m_value.object->size() - 1; ++cnt, ++i)
17098 {
17099 o->write_character('\"');
17100 dump_escaped(i->first, ensure_ascii);
17101 o->write_characters("\":", 2);
17102 dump(i->second, false, ensure_ascii, indent_step, current_indent);
17103 o->write_character(',');
17104 }
17105
17106 // last element
17107 JSON_ASSERT(i != val.m_value.object->cend());
17108 JSON_ASSERT(std::next(i) == val.m_value.object->cend());
17109 o->write_character('\"');
17110 dump_escaped(i->first, ensure_ascii);
17111 o->write_characters("\":", 2);
17112 dump(i->second, false, ensure_ascii, indent_step, current_indent);
17113
17114 o->write_character('}');
17115 }
17116
17117 return;
17118 }
17119
17120 case value_t::array:
17121 {
17122 if (val.m_value.array->empty())
17123 {
17124 o->write_characters("[]", 2);
17125 return;
17126 }
17127
17128 if (pretty_print)
17129 {
17130 o->write_characters("[\n", 2);
17131
17132 // variable to hold indentation for recursive calls
17133 const auto new_indent = current_indent + indent_step;
17134 if (JSON_HEDLEY_UNLIKELY(indent_string.size() < new_indent))
17135 {
17136 indent_string.resize(indent_string.size() * 2, ' ');
17137 }
17138
17139 // first n-1 elements
17140 for (auto i = val.m_value.array->cbegin();
17141 i != val.m_value.array->cend() - 1; ++i)
17142 {
17143 o->write_characters(indent_string.c_str(), new_indent);
17144 dump(*i, true, ensure_ascii, indent_step, new_indent);
17145 o->write_characters(",\n", 2);
17146 }
17147
17148 // last element
17149 JSON_ASSERT(!val.m_value.array->empty());
17150 o->write_characters(indent_string.c_str(), new_indent);
17151 dump(val.m_value.array->back(), true, ensure_ascii, indent_step, new_indent);
17152
17153 o->write_character('\n');
17154 o->write_characters(indent_string.c_str(), current_indent);
17155 o->write_character(']');
17156 }
17157 else
17158 {
17159 o->write_character('[');
17160
17161 // first n-1 elements
17162 for (auto i = val.m_value.array->cbegin();
17163 i != val.m_value.array->cend() - 1; ++i)
17164 {
17165 dump(*i, false, ensure_ascii, indent_step, current_indent);
17166 o->write_character(',');
17167 }
17168
17169 // last element
17170 JSON_ASSERT(!val.m_value.array->empty());
17171 dump(val.m_value.array->back(), false, ensure_ascii, indent_step, current_indent);
17172
17173 o->write_character(']');
17174 }
17175
17176 return;
17177 }
17178
17179 case value_t::string:
17180 {
17181 o->write_character('\"');
17182 dump_escaped(*val.m_value.string, ensure_ascii);
17183 o->write_character('\"');
17184 return;
17185 }
17186
17187 case value_t::binary:
17188 {
17189 if (pretty_print)
17190 {
17191 o->write_characters("{\n", 2);
17192
17193 // variable to hold indentation for recursive calls
17194 const auto new_indent = current_indent + indent_step;
17195 if (JSON_HEDLEY_UNLIKELY(indent_string.size() < new_indent))
17196 {
17197 indent_string.resize(indent_string.size() * 2, ' ');
17198 }
17199
17200 o->write_characters(indent_string.c_str(), new_indent);
17201
17202 o->write_characters("\"bytes\": [", 10);
17203
17204 if (!val.m_value.binary->empty())
17205 {
17206 for (auto i = val.m_value.binary->cbegin();
17207 i != val.m_value.binary->cend() - 1; ++i)
17208 {
17209 dump_integer(*i);
17210 o->write_characters(", ", 2);
17211 }
17212 dump_integer(val.m_value.binary->back());
17213 }
17214
17215 o->write_characters("],\n", 3);
17216 o->write_characters(indent_string.c_str(), new_indent);
17217
17218 o->write_characters("\"subtype\": ", 11);
17219 if (val.m_value.binary->has_subtype())
17220 {
17221 dump_integer(val.m_value.binary->subtype());
17222 }
17223 else
17224 {
17225 o->write_characters("null", 4);
17226 }
17227 o->write_character('\n');
17228 o->write_characters(indent_string.c_str(), current_indent);
17229 o->write_character('}');
17230 }
17231 else
17232 {
17233 o->write_characters("{\"bytes\":[", 10);
17234
17235 if (!val.m_value.binary->empty())
17236 {
17237 for (auto i = val.m_value.binary->cbegin();
17238 i != val.m_value.binary->cend() - 1; ++i)
17239 {
17240 dump_integer(*i);
17241 o->write_character(',');
17242 }
17243 dump_integer(val.m_value.binary->back());
17244 }
17245
17246 o->write_characters("],\"subtype\":", 12);
17247 if (val.m_value.binary->has_subtype())
17248 {
17249 dump_integer(val.m_value.binary->subtype());
17250 o->write_character('}');
17251 }
17252 else
17253 {
17254 o->write_characters("null}", 5);
17255 }
17256 }
17257 return;
17258 }
17259
17260 case value_t::boolean:
17261 {
17262 if (val.m_value.boolean)
17263 {
17264 o->write_characters("true", 4);
17265 }
17266 else
17267 {
17268 o->write_characters("false", 5);
17269 }
17270 return;
17271 }
17272
17274 {
17275 dump_integer(val.m_value.number_integer);
17276 return;
17277 }
17278
17280 {
17281 dump_integer(val.m_value.number_unsigned);
17282 return;
17283 }
17284
17286 {
17287 dump_float(val.m_value.number_float);
17288 return;
17289 }
17290
17291 case value_t::discarded:
17292 {
17293 o->write_characters("<discarded>", 11);
17294 return;
17295 }
17296
17297 case value_t::null:
17298 {
17299 o->write_characters("null", 4);
17300 return;
17301 }
17302
17303 default: // LCOV_EXCL_LINE
17304 JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert) LCOV_EXCL_LINE
17305 }
17306 }
17307
17323 void dump_escaped(const string_t& s, const bool ensure_ascii)
17324 {
17325 std::uint32_t codepoint{};
17326 std::uint8_t state = UTF8_ACCEPT;
17327 std::size_t bytes = 0; // number of bytes written to string_buffer
17328
17329 // number of bytes written at the point of the last valid byte
17331 std::size_t undumped_chars = 0;
17332
17333 for (std::size_t i = 0; i < s.size(); ++i)
17334 {
17335 const auto byte = static_cast<std::uint8_t>(s[i]);
17336
17337 switch (decode(state, codepoint, byte))
17338 {
17339 case UTF8_ACCEPT: // decode found a new code point
17340 {
17341 switch (codepoint)
17342 {
17343 case 0x08: // backspace
17344 {
17345 string_buffer[bytes++] = '\\';
17346 string_buffer[bytes++] = 'b';
17347 break;
17348 }
17349
17350 case 0x09: // horizontal tab
17351 {
17352 string_buffer[bytes++] = '\\';
17353 string_buffer[bytes++] = 't';
17354 break;
17355 }
17356
17357 case 0x0A: // newline
17358 {
17359 string_buffer[bytes++] = '\\';
17360 string_buffer[bytes++] = 'n';
17361 break;
17362 }
17363
17364 case 0x0C: // formfeed
17365 {
17366 string_buffer[bytes++] = '\\';
17367 string_buffer[bytes++] = 'f';
17368 break;
17369 }
17370
17371 case 0x0D: // carriage return
17372 {
17373 string_buffer[bytes++] = '\\';
17374 string_buffer[bytes++] = 'r';
17375 break;
17376 }
17377
17378 case 0x22: // quotation mark
17379 {
17380 string_buffer[bytes++] = '\\';
17381 string_buffer[bytes++] = '\"';
17382 break;
17383 }
17384
17385 case 0x5C: // reverse solidus
17386 {
17387 string_buffer[bytes++] = '\\';
17388 string_buffer[bytes++] = '\\';
17389 break;
17390 }
17391
17392 default:
17393 {
17394 // escape control characters (0x00..0x1F) or, if
17395 // ensure_ascii parameter is used, non-ASCII characters
17396 if ((codepoint <= 0x1F) || (ensure_ascii && (codepoint >= 0x7F)))
17397 {
17398 if (codepoint <= 0xFFFF)
17399 {
17400 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-vararg,hicpp-vararg)
17401 static_cast<void>((std::snprintf)(string_buffer.data() + bytes, 7, "\\u%04x",
17402 static_cast<std::uint16_t>(codepoint)));
17403 bytes += 6;
17404 }
17405 else
17406 {
17407 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-vararg,hicpp-vararg)
17408 static_cast<void>((std::snprintf)(string_buffer.data() + bytes, 13, "\\u%04x\\u%04x",
17409 static_cast<std::uint16_t>(0xD7C0u + (codepoint >> 10u)),
17410 static_cast<std::uint16_t>(0xDC00u + (codepoint & 0x3FFu))));
17411 bytes += 12;
17412 }
17413 }
17414 else
17415 {
17416 // copy byte to buffer (all previous bytes
17417 // been copied have in default case above)
17418 string_buffer[bytes++] = s[i];
17419 }
17420 break;
17421 }
17422 }
17423
17424 // write buffer and reset index; there must be 13 bytes
17425 // left, as this is the maximal number of bytes to be
17426 // written ("\uxxxx\uxxxx\0") for one code point
17427 if (string_buffer.size() - bytes < 13)
17428 {
17429 o->write_characters(string_buffer.data(), bytes);
17430 bytes = 0;
17431 }
17432
17433 // remember the byte position of this accept
17435 undumped_chars = 0;
17436 break;
17437 }
17438
17439 case UTF8_REJECT: // decode found invalid UTF-8 byte
17440 {
17441 switch (error_handler)
17442 {
17444 {
17445 JSON_THROW(type_error::create(316, concat("invalid UTF-8 byte at index ", std::to_string(i), ": 0x", hex_bytes(byte | 0)), nullptr));
17446 }
17447
17450 {
17451 // in case we saw this character the first time, we
17452 // would like to read it again, because the byte
17453 // may be OK for itself, but just not OK for the
17454 // previous sequence
17455 if (undumped_chars > 0)
17456 {
17457 --i;
17458 }
17459
17460 // reset length buffer to the last accepted index;
17461 // thus removing/ignoring the invalid characters
17463
17465 {
17466 // add a replacement character
17467 if (ensure_ascii)
17468 {
17469 string_buffer[bytes++] = '\\';
17470 string_buffer[bytes++] = 'u';
17471 string_buffer[bytes++] = 'f';
17472 string_buffer[bytes++] = 'f';
17473 string_buffer[bytes++] = 'f';
17474 string_buffer[bytes++] = 'd';
17475 }
17476 else
17477 {
17478 string_buffer[bytes++] = detail::binary_writer<BasicJsonType, char>::to_char_type('\xEF');
17479 string_buffer[bytes++] = detail::binary_writer<BasicJsonType, char>::to_char_type('\xBF');
17480 string_buffer[bytes++] = detail::binary_writer<BasicJsonType, char>::to_char_type('\xBD');
17481 }
17482
17483 // write buffer and reset index; there must be 13 bytes
17484 // left, as this is the maximal number of bytes to be
17485 // written ("\uxxxx\uxxxx\0") for one code point
17486 if (string_buffer.size() - bytes < 13)
17487 {
17488 o->write_characters(string_buffer.data(), bytes);
17489 bytes = 0;
17490 }
17491
17493 }
17494
17495 undumped_chars = 0;
17496
17497 // continue processing the string
17498 state = UTF8_ACCEPT;
17499 break;
17500 }
17501
17502 default: // LCOV_EXCL_LINE
17503 JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert) LCOV_EXCL_LINE
17504 }
17505 break;
17506 }
17507
17508 default: // decode found yet incomplete multi-byte code point
17509 {
17510 if (!ensure_ascii)
17511 {
17512 // code point will not be escaped - copy byte to buffer
17513 string_buffer[bytes++] = s[i];
17514 }
17516 break;
17517 }
17518 }
17519 }
17520
17521 // we finished processing the string
17522 if (JSON_HEDLEY_LIKELY(state == UTF8_ACCEPT))
17523 {
17524 // write buffer
17525 if (bytes > 0)
17526 {
17527 o->write_characters(string_buffer.data(), bytes);
17528 }
17529 }
17530 else
17531 {
17532 // we finish reading, but do not accept: string was incomplete
17533 switch (error_handler)
17534 {
17536 {
17537 JSON_THROW(type_error::create(316, concat("incomplete UTF-8 string; last byte: 0x", hex_bytes(static_cast<std::uint8_t>(s.back() | 0))), nullptr));
17538 }
17539
17541 {
17542 // write all accepted bytes
17543 o->write_characters(string_buffer.data(), bytes_after_last_accept);
17544 break;
17545 }
17546
17548 {
17549 // write all accepted bytes
17550 o->write_characters(string_buffer.data(), bytes_after_last_accept);
17551 // add a replacement character
17552 if (ensure_ascii)
17553 {
17554 o->write_characters("\\ufffd", 6);
17555 }
17556 else
17557 {
17558 o->write_characters("\xEF\xBF\xBD", 3);
17559 }
17560 break;
17561 }
17562
17563 default: // LCOV_EXCL_LINE
17564 JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert) LCOV_EXCL_LINE
17565 }
17566 }
17567 }
17568
17569 private:
17578 inline unsigned int count_digits(number_unsigned_t x) noexcept
17579 {
17580 unsigned int n_digits = 1;
17581 for (;;)
17582 {
17583 if (x < 10)
17584 {
17585 return n_digits;
17586 }
17587 if (x < 100)
17588 {
17589 return n_digits + 1;
17590 }
17591 if (x < 1000)
17592 {
17593 return n_digits + 2;
17594 }
17595 if (x < 10000)
17596 {
17597 return n_digits + 3;
17598 }
17599 x = x / 10000u;
17600 n_digits += 4;
17601 }
17602 }
17603
17609 static std::string hex_bytes(std::uint8_t byte)
17610 {
17611 std::string result = "FF";
17612 constexpr const char* nibble_to_hex = "0123456789ABCDEF";
17613 result[0] = nibble_to_hex[byte / 16];
17614 result[1] = nibble_to_hex[byte % 16];
17615 return result;
17616 }
17617
17618 // templates to avoid warnings about useless casts
17619 template <typename NumberType, enable_if_t<std::is_signed<NumberType>::value, int> = 0>
17620 bool is_negative_number(NumberType x)
17621 {
17622 return x < 0;
17623 }
17624
17625 template < typename NumberType, enable_if_t <std::is_unsigned<NumberType>::value, int > = 0 >
17626 bool is_negative_number(NumberType /*unused*/)
17627 {
17628 return false;
17629 }
17630
17640 template < typename NumberType, detail::enable_if_t <
17641 std::is_integral<NumberType>::value ||
17642 std::is_same<NumberType, number_unsigned_t>::value ||
17643 std::is_same<NumberType, number_integer_t>::value ||
17644 std::is_same<NumberType, binary_char_t>::value,
17645 int > = 0 >
17646 void dump_integer(NumberType x)
17647 {
17648 static constexpr std::array<std::array<char, 2>, 100> digits_to_99
17649 {
17650 {
17651 {{'0', '0'}}, {{'0', '1'}}, {{'0', '2'}}, {{'0', '3'}}, {{'0', '4'}}, {{'0', '5'}}, {{'0', '6'}}, {{'0', '7'}}, {{'0', '8'}}, {{'0', '9'}},
17652 {{'1', '0'}}, {{'1', '1'}}, {{'1', '2'}}, {{'1', '3'}}, {{'1', '4'}}, {{'1', '5'}}, {{'1', '6'}}, {{'1', '7'}}, {{'1', '8'}}, {{'1', '9'}},
17653 {{'2', '0'}}, {{'2', '1'}}, {{'2', '2'}}, {{'2', '3'}}, {{'2', '4'}}, {{'2', '5'}}, {{'2', '6'}}, {{'2', '7'}}, {{'2', '8'}}, {{'2', '9'}},
17654 {{'3', '0'}}, {{'3', '1'}}, {{'3', '2'}}, {{'3', '3'}}, {{'3', '4'}}, {{'3', '5'}}, {{'3', '6'}}, {{'3', '7'}}, {{'3', '8'}}, {{'3', '9'}},
17655 {{'4', '0'}}, {{'4', '1'}}, {{'4', '2'}}, {{'4', '3'}}, {{'4', '4'}}, {{'4', '5'}}, {{'4', '6'}}, {{'4', '7'}}, {{'4', '8'}}, {{'4', '9'}},
17656 {{'5', '0'}}, {{'5', '1'}}, {{'5', '2'}}, {{'5', '3'}}, {{'5', '4'}}, {{'5', '5'}}, {{'5', '6'}}, {{'5', '7'}}, {{'5', '8'}}, {{'5', '9'}},
17657 {{'6', '0'}}, {{'6', '1'}}, {{'6', '2'}}, {{'6', '3'}}, {{'6', '4'}}, {{'6', '5'}}, {{'6', '6'}}, {{'6', '7'}}, {{'6', '8'}}, {{'6', '9'}},
17658 {{'7', '0'}}, {{'7', '1'}}, {{'7', '2'}}, {{'7', '3'}}, {{'7', '4'}}, {{'7', '5'}}, {{'7', '6'}}, {{'7', '7'}}, {{'7', '8'}}, {{'7', '9'}},
17659 {{'8', '0'}}, {{'8', '1'}}, {{'8', '2'}}, {{'8', '3'}}, {{'8', '4'}}, {{'8', '5'}}, {{'8', '6'}}, {{'8', '7'}}, {{'8', '8'}}, {{'8', '9'}},
17660 {{'9', '0'}}, {{'9', '1'}}, {{'9', '2'}}, {{'9', '3'}}, {{'9', '4'}}, {{'9', '5'}}, {{'9', '6'}}, {{'9', '7'}}, {{'9', '8'}}, {{'9', '9'}},
17661 }
17662 };
17663
17664 // special case for "0"
17665 if (x == 0)
17666 {
17667 o->write_character('0');
17668 return;
17669 }
17670
17671 // use a pointer to fill the buffer
17672 auto buffer_ptr = number_buffer.begin(); // NOLINT(llvm-qualified-auto,readability-qualified-auto,cppcoreguidelines-pro-type-vararg,hicpp-vararg)
17673
17674 number_unsigned_t abs_value;
17675
17676 unsigned int n_chars{};
17677
17678 if (is_negative_number(x))
17679 {
17680 *buffer_ptr = '-';
17681 abs_value = remove_sign(static_cast<number_integer_t>(x));
17682
17683 // account one more byte for the minus sign
17684 n_chars = 1 + count_digits(abs_value);
17685 }
17686 else
17687 {
17688 abs_value = static_cast<number_unsigned_t>(x);
17689 n_chars = count_digits(abs_value);
17690 }
17691
17692 // spare 1 byte for '\0'
17693 JSON_ASSERT(n_chars < number_buffer.size() - 1);
17694
17695 // jump to the end to generate the string from backward,
17696 // so we later avoid reversing the result
17697 buffer_ptr += n_chars;
17698
17699 // Fast int2ascii implementation inspired by "Fastware" talk by Andrei Alexandrescu
17700 // See: https://www.youtube.com/watch?v=o4-CwDo2zpg
17701 while (abs_value >= 100)
17702 {
17703 const auto digits_index = static_cast<unsigned>((abs_value % 100));
17704 abs_value /= 100;
17705 *(--buffer_ptr) = digits_to_99[digits_index][1];
17706 *(--buffer_ptr) = digits_to_99[digits_index][0];
17707 }
17708
17709 if (abs_value >= 10)
17710 {
17711 const auto digits_index = static_cast<unsigned>(abs_value);
17712 *(--buffer_ptr) = digits_to_99[digits_index][1];
17713 *(--buffer_ptr) = digits_to_99[digits_index][0];
17714 }
17715 else
17716 {
17717 *(--buffer_ptr) = static_cast<char>('0' + abs_value);
17718 }
17719
17720 o->write_characters(number_buffer.data(), n_chars);
17721 }
17722
17731 void dump_float(number_float_t x)
17732 {
17733 // NaN / inf
17734 if (!std::isfinite(x))
17735 {
17736 o->write_characters("null", 4);
17737 return;
17738 }
17739
17740 // If number_float_t is an IEEE-754 single or double precision number,
17741 // use the Grisu2 algorithm to produce short numbers which are
17742 // guaranteed to round-trip, using strtof and strtod, resp.
17743 //
17744 // NB: The test below works if <long double> == <double>.
17745 static constexpr bool is_ieee_single_or_double
17746 = (std::numeric_limits<number_float_t>::is_iec559 && std::numeric_limits<number_float_t>::digits == 24 && std::numeric_limits<number_float_t>::max_exponent == 128) ||
17747 (std::numeric_limits<number_float_t>::is_iec559 && std::numeric_limits<number_float_t>::digits == 53 && std::numeric_limits<number_float_t>::max_exponent == 1024);
17748
17749 dump_float(x, std::integral_constant<bool, is_ieee_single_or_double>());
17750 }
17751
17752 void dump_float(number_float_t x, std::true_type /*is_ieee_single_or_double*/)
17753 {
17754 auto* begin = number_buffer.data();
17755 auto* end = ::nlohmann::detail::to_chars(begin, begin + number_buffer.size(), x);
17756
17757 o->write_characters(begin, static_cast<size_t>(end - begin));
17758 }
17759
17760 void dump_float(number_float_t x, std::false_type /*is_ieee_single_or_double*/)
17761 {
17762 // get number of digits for a float -> text -> float round-trip
17763 static constexpr auto d = std::numeric_limits<number_float_t>::max_digits10;
17764
17765 // the actual conversion
17766 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-vararg,hicpp-vararg)
17767 std::ptrdiff_t len = (std::snprintf)(number_buffer.data(), number_buffer.size(), "%.*g", d, x);
17768
17769 // negative value indicates an error
17770 JSON_ASSERT(len > 0);
17771 // check if buffer was large enough
17772 JSON_ASSERT(static_cast<std::size_t>(len) < number_buffer.size());
17773
17774 // erase thousands separator
17775 if (thousands_sep != '\0')
17776 {
17777 // NOLINTNEXTLINE(readability-qualified-auto,llvm-qualified-auto): std::remove returns an iterator, see https://github.com/nlohmann/json/issues/3081
17778 const auto end = std::remove(number_buffer.begin(), number_buffer.begin() + len, thousands_sep);
17779 std::fill(end, number_buffer.end(), '\0');
17780 JSON_ASSERT((end - number_buffer.begin()) <= len);
17781 len = (end - number_buffer.begin());
17782 }
17783
17784 // convert decimal point to '.'
17785 if (decimal_point != '\0' && decimal_point != '.')
17786 {
17787 // NOLINTNEXTLINE(readability-qualified-auto,llvm-qualified-auto): std::find returns an iterator, see https://github.com/nlohmann/json/issues/3081
17788 const auto dec_pos = std::find(number_buffer.begin(), number_buffer.end(), decimal_point);
17789 if (dec_pos != number_buffer.end())
17790 {
17791 *dec_pos = '.';
17792 }
17793 }
17794
17795 o->write_characters(number_buffer.data(), static_cast<std::size_t>(len));
17796
17797 // determine if we need to append ".0"
17798 const bool value_is_int_like =
17799 std::none_of(number_buffer.begin(), number_buffer.begin() + len + 1,
17800 [](char c)
17801 {
17802 return c == '.' || c == 'e';
17803 });
17804
17805 if (value_is_int_like)
17806 {
17807 o->write_characters(".0", 2);
17808 }
17809 }
17810
17832 static std::uint8_t decode(std::uint8_t& state, std::uint32_t& codep, const std::uint8_t byte) noexcept
17833 {
17834 static const std::array<std::uint8_t, 400> utf8d =
17835 {
17836 {
17837 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 00..1F
17838 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 20..3F
17839 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 40..5F
17840 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 60..7F
17841 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, // 80..9F
17842 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, // A0..BF
17843 8, 8, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, // C0..DF
17844 0xA, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x4, 0x3, 0x3, // E0..EF
17845 0xB, 0x6, 0x6, 0x6, 0x5, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, // F0..FF
17846 0x0, 0x1, 0x2, 0x3, 0x5, 0x8, 0x7, 0x1, 0x1, 0x1, 0x4, 0x6, 0x1, 0x1, 0x1, 0x1, // s0..s0
17847 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, // s1..s2
17848 1, 2, 1, 1, 1, 1, 1, 2, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, // s3..s4
17849 1, 2, 1, 1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 1, 3, 1, 1, 1, 1, 1, 1, // s5..s6
17850 1, 3, 1, 1, 1, 1, 1, 3, 1, 3, 1, 1, 1, 1, 1, 1, 1, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 // s7..s8
17851 }
17852 };
17853
17854 JSON_ASSERT(byte < utf8d.size());
17855 const std::uint8_t type = utf8d[byte];
17856
17857 codep = (state != UTF8_ACCEPT)
17858 ? (byte & 0x3fu) | (codep << 6u)
17859 : (0xFFu >> type) & (byte);
17860
17861 std::size_t index = 256u + static_cast<size_t>(state) * 16u + static_cast<size_t>(type);
17862 JSON_ASSERT(index < 400);
17863 state = utf8d[index];
17864 return state;
17865 }
17866
17867 /*
17868 * Overload to make the compiler happy while it is instantiating
17869 * dump_integer for number_unsigned_t.
17870 * Must never be called.
17871 */
17872 number_unsigned_t remove_sign(number_unsigned_t x)
17873 {
17874 JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert) LCOV_EXCL_LINE
17875 return x; // LCOV_EXCL_LINE
17876 }
17877
17878 /*
17879 * Helper function for dump_integer
17880 *
17881 * This function takes a negative signed integer and returns its absolute
17882 * value as unsigned integer. The plus/minus shuffling is necessary as we can
17883 * not directly remove the sign of an arbitrary signed integer as the
17884 * absolute values of INT_MIN and INT_MAX are usually not the same. See
17885 * #1708 for details.
17886 */
17887 inline number_unsigned_t remove_sign(number_integer_t x) noexcept
17888 {
17889 JSON_ASSERT(x < 0 && x < (std::numeric_limits<number_integer_t>::max)()); // NOLINT(misc-redundant-expression)
17890 return static_cast<number_unsigned_t>(-(x + 1)) + 1;
17891 }
17892
17893 private:
17895 output_adapter_t<char> o = nullptr;
17896
17898 std::array<char, 64> number_buffer{{}};
17899
17901 const std::lconv* loc = nullptr;
17903 const char thousands_sep = '\0';
17905 const char decimal_point = '\0';
17906
17908 std::array<char, 512> string_buffer{{}};
17909
17911 const char indent_char;
17914
17917};
17918} // namespace detail
17919} // namespace nlohmann
17920
17921// #include <nlohmann/detail/value_t.hpp>
17922
17923// #include <nlohmann/json_fwd.hpp>
17924
17925// #include <nlohmann/ordered_map.hpp>
17926
17927
17928#include <functional> // equal_to, less
17929#include <initializer_list> // initializer_list
17930#include <iterator> // input_iterator_tag, iterator_traits
17931#include <memory> // allocator
17932#include <stdexcept> // for out_of_range
17933#include <type_traits> // enable_if, is_convertible
17934#include <utility> // pair
17935#include <vector> // vector
17936
17937// #include <nlohmann/detail/macro_scope.hpp>
17938
17939
17940namespace nlohmann
17941{
17942
17945template <class Key, class T, class IgnoredLess = std::less<Key>,
17946 class Allocator = std::allocator<std::pair<const Key, T>>>
17947 struct ordered_map : std::vector<std::pair<const Key, T>, Allocator>
17948{
17949 using key_type = Key;
17950 using mapped_type = T;
17951 using Container = std::vector<std::pair<const Key, T>, Allocator>;
17952 using iterator = typename Container::iterator;
17953 using const_iterator = typename Container::const_iterator;
17954 using size_type = typename Container::size_type;
17955 using value_type = typename Container::value_type;
17956#ifdef JSON_HAS_CPP_14
17957 using key_compare = std::equal_to<>;
17958#else
17959 using key_compare = std::equal_to<Key>;
17960#endif
17961
17962 // Explicit constructors instead of `using Container::Container`
17963 // otherwise older compilers choke on it (GCC <= 5.5, xcode <= 9.4)
17964 ordered_map() noexcept(noexcept(Container())) : Container{} {}
17965 explicit ordered_map(const Allocator& alloc) noexcept(noexcept(Container(alloc))) : Container{alloc} {}
17966 template <class It>
17967 ordered_map(It first, It last, const Allocator& alloc = Allocator())
17968 : Container{first, last, alloc} {}
17969 ordered_map(std::initializer_list<value_type> init, const Allocator& alloc = Allocator() )
17970 : Container{init, alloc} {}
17971
17972 std::pair<iterator, bool> emplace(const key_type& key, T&& t)
17973 {
17974 for (auto it = this->begin(); it != this->end(); ++it)
17975 {
17976 if (m_compare(it->first, key))
17977 {
17978 return {it, false};
17979 }
17980 }
17981 Container::emplace_back(key, t);
17982 return {--this->end(), true};
17983 }
17984
17985 T& operator[](const Key& key)
17986 {
17987 return emplace(key, T{}).first->second;
17988 }
17989
17990 const T& operator[](const Key& key) const
17991 {
17992 return at(key);
17993 }
17994
17995 T& at(const Key& key)
17996 {
17997 for (auto it = this->begin(); it != this->end(); ++it)
17998 {
17999 if (m_compare(it->first, key))
18000 {
18001 return it->second;
18002 }
18003 }
18004
18005 JSON_THROW(std::out_of_range("key not found"));
18006 }
18007
18008 const T& at(const Key& key) const
18009 {
18010 for (auto it = this->begin(); it != this->end(); ++it)
18011 {
18012 if (m_compare(it->first, key))
18013 {
18014 return it->second;
18015 }
18016 }
18017
18018 JSON_THROW(std::out_of_range("key not found"));
18019 }
18020
18021 size_type erase(const Key& key)
18022 {
18023 for (auto it = this->begin(); it != this->end(); ++it)
18024 {
18025 if (m_compare(it->first, key))
18026 {
18027 // Since we cannot move const Keys, re-construct them in place
18028 for (auto next = it; ++next != this->end(); ++it)
18029 {
18030 it->~value_type(); // Destroy but keep allocation
18031 new (&*it) value_type{std::move(*next)};
18032 }
18033 Container::pop_back();
18034 return 1;
18035 }
18036 }
18037 return 0;
18038 }
18039
18041 {
18042 return erase(pos, std::next(pos));
18043 }
18044
18046 {
18047 const auto elements_affected = std::distance(first, last);
18048 const auto offset = std::distance(Container::begin(), first);
18049
18050 // This is the start situation. We need to delete elements_affected
18051 // elements (3 in this example: e, f, g), and need to return an
18052 // iterator past the last deleted element (h in this example).
18053 // Note that offset is the distance from the start of the vector
18054 // to first. We will need this later.
18055
18056 // [ a, b, c, d, e, f, g, h, i, j ]
18057 // ^ ^
18058 // first last
18059
18060 // Since we cannot move const Keys, we re-construct them in place.
18061 // We start at first and re-construct (viz. copy) the elements from
18062 // the back of the vector. Example for first iteration:
18063
18064 // ,--------.
18065 // v | destroy e and re-construct with h
18066 // [ a, b, c, d, e, f, g, h, i, j ]
18067 // ^ ^
18068 // it it + elements_affected
18069
18070 for (auto it = first; std::next(it, elements_affected) != Container::end(); ++it)
18071 {
18072 it->~value_type(); // destroy but keep allocation
18073 new (&*it) value_type{std::move(*std::next(it, elements_affected))}; // "move" next element to it
18074 }
18075
18076 // [ a, b, c, d, h, i, j, h, i, j ]
18077 // ^ ^
18078 // first last
18079
18080 // remove the unneeded elements at the end of the vector
18081 Container::resize(this->size() - static_cast<size_type>(elements_affected));
18082
18083 // [ a, b, c, d, h, i, j ]
18084 // ^ ^
18085 // first last
18086
18087 // first is now pointing past the last deleted element, but we cannot
18088 // use this iterator, because it may have been invalidated by the
18089 // resize call. Instead, we can return begin() + offset.
18090 return Container::begin() + offset;
18091 }
18092
18093 size_type count(const Key& key) const
18094 {
18095 for (auto it = this->begin(); it != this->end(); ++it)
18096 {
18097 if (m_compare(it->first, key))
18098 {
18099 return 1;
18100 }
18101 }
18102 return 0;
18103 }
18104
18105 iterator find(const Key& key)
18106 {
18107 for (auto it = this->begin(); it != this->end(); ++it)
18108 {
18109 if (m_compare(it->first, key))
18110 {
18111 return it;
18112 }
18113 }
18114 return Container::end();
18115 }
18116
18117 const_iterator find(const Key& key) const
18118 {
18119 for (auto it = this->begin(); it != this->end(); ++it)
18120 {
18121 if (m_compare(it->first, key))
18122 {
18123 return it;
18124 }
18125 }
18126 return Container::end();
18127 }
18128
18129 std::pair<iterator, bool> insert( value_type&& value )
18130 {
18131 return emplace(value.first, std::move(value.second));
18132 }
18133
18134 std::pair<iterator, bool> insert( const value_type& value )
18135 {
18136 for (auto it = this->begin(); it != this->end(); ++it)
18137 {
18138 if (m_compare(it->first, value.first))
18139 {
18140 return {it, false};
18141 }
18142 }
18143 Container::push_back(value);
18144 return {--this->end(), true};
18145 }
18146
18147 template<typename InputIt>
18148 using require_input_iter = typename std::enable_if<std::is_convertible<typename std::iterator_traits<InputIt>::iterator_category,
18149 std::input_iterator_tag>::value>::type;
18150
18151 template<typename InputIt, typename = require_input_iter<InputIt>>
18152 void insert(InputIt first, InputIt last)
18153 {
18154 for (auto it = first; it != last; ++it)
18155 {
18156 insert(*it);
18157 }
18158 }
18159
18160private:
18162};
18163
18164} // namespace nlohmann
18165
18166
18167#if defined(JSON_HAS_CPP_17)
18168 #include <any>
18169 #include <string_view>
18170#endif
18171
18177namespace nlohmann
18178{
18179
18199class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-special-member-functions)
18200{
18201 private:
18202 template<detail::value_t> friend struct detail::external_constructor;
18203
18204 template<typename>
18205 friend class ::nlohmann::json_pointer;
18206 // can be restored when json_pointer backwards compatibility is removed
18207 // friend ::nlohmann::json_pointer<StringType>;
18208
18209 template<typename BasicJsonType, typename InputType>
18210 friend class ::nlohmann::detail::parser;
18211 friend ::nlohmann::detail::serializer<basic_json>;
18212 template<typename BasicJsonType>
18213 friend class ::nlohmann::detail::iter_impl;
18214 template<typename BasicJsonType, typename CharType>
18215 friend class ::nlohmann::detail::binary_writer;
18216 template<typename BasicJsonType, typename InputType, typename SAX>
18217 friend class ::nlohmann::detail::binary_reader;
18218 template<typename BasicJsonType>
18219 friend class ::nlohmann::detail::json_sax_dom_parser;
18220 template<typename BasicJsonType>
18221 friend class ::nlohmann::detail::json_sax_dom_callback_parser;
18222 friend class ::nlohmann::detail::exception;
18223
18225 using basic_json_t = NLOHMANN_BASIC_JSON_TPL;
18226
18228 // convenience aliases for types residing in namespace detail;
18230
18231 template<typename InputAdapterType>
18232 static ::nlohmann::detail::parser<basic_json, InputAdapterType> parser(
18233 InputAdapterType adapter,
18234 detail::parser_callback_t<basic_json>cb = nullptr,
18235 const bool allow_exceptions = true,
18236 const bool ignore_comments = false
18237 )
18238 {
18239 return ::nlohmann::detail::parser<basic_json, InputAdapterType>(std::move(adapter),
18240 std::move(cb), allow_exceptions, ignore_comments);
18241 }
18242
18243 private:
18244 using primitive_iterator_t = ::nlohmann::detail::primitive_iterator_t;
18245 template<typename BasicJsonType>
18247 template<typename BasicJsonType>
18249 template<typename Iterator>
18250 using iteration_proxy = ::nlohmann::detail::iteration_proxy<Iterator>;
18251 template<typename Base> using json_reverse_iterator = ::nlohmann::detail::json_reverse_iterator<Base>;
18252
18253 template<typename CharType>
18254 using output_adapter_t = ::nlohmann::detail::output_adapter_t<CharType>;
18255
18256 template<typename InputType>
18258 template<typename CharType> using binary_writer = ::nlohmann::detail::binary_writer<basic_json, CharType>;
18259
18262
18263 public:
18267 template<typename T, typename SFINAE>
18268 using json_serializer = JSONSerializer<T, SFINAE>;
18274 using initializer_list_t = std::initializer_list<detail::json_ref<basic_json>>;
18275
18276 using input_format_t = detail::input_format_t;
18278 using json_sax_t = json_sax<basic_json>;
18279
18281 // exceptions //
18283
18287
18294
18296
18297
18299 // container types //
18301
18306
18309
18314
18316 using difference_type = std::ptrdiff_t;
18318 using size_type = std::size_t;
18319
18321 using allocator_type = AllocatorType<basic_json>;
18322
18324 using pointer = typename std::allocator_traits<allocator_type>::pointer;
18326 using const_pointer = typename std::allocator_traits<allocator_type>::const_pointer;
18327
18336
18338
18339
18343 {
18344 return allocator_type();
18345 }
18346
18351 {
18353
18354 result["copyright"] = "(C) 2013-2022 Niels Lohmann";
18355 result["name"] = "JSON for Modern C++";
18356 result["url"] = "https://github.com/nlohmann/json";
18357 result["version"]["string"] =
18358 detail::concat(std::to_string(NLOHMANN_JSON_VERSION_MAJOR), '.',
18359 std::to_string(NLOHMANN_JSON_VERSION_MINOR), '.',
18360 std::to_string(NLOHMANN_JSON_VERSION_PATCH));
18361 result["version"]["major"] = NLOHMANN_JSON_VERSION_MAJOR;
18362 result["version"]["minor"] = NLOHMANN_JSON_VERSION_MINOR;
18363 result["version"]["patch"] = NLOHMANN_JSON_VERSION_PATCH;
18364
18365#ifdef _WIN32
18366 result["platform"] = "win32";
18367#elif defined __linux__
18368 result["platform"] = "linux";
18369#elif defined __APPLE__
18370 result["platform"] = "apple";
18371#elif defined __unix__
18372 result["platform"] = "unix";
18373#else
18374 result["platform"] = "unknown";
18375#endif
18376
18377#if defined(__ICC) || defined(__INTEL_COMPILER)
18378 result["compiler"] = {{"family", "icc"}, {"version", __INTEL_COMPILER}};
18379#elif defined(__clang__)
18380 result["compiler"] = {{"family", "clang"}, {"version", __clang_version__}};
18381#elif defined(__GNUC__) || defined(__GNUG__)
18382 result["compiler"] = {{"family", "gcc"}, {"version", detail::concat(
18383 std::to_string(__GNUC__), '.',
18384 std::to_string(__GNUC_MINOR__), '.',
18385 std::to_string(__GNUC_PATCHLEVEL__))
18386 }
18387 };
18388#elif defined(__HP_cc) || defined(__HP_aCC)
18389 result["compiler"] = "hp"
18390#elif defined(__IBMCPP__)
18391 result["compiler"] = {{"family", "ilecpp"}, {"version", __IBMCPP__}};
18392#elif defined(_MSC_VER)
18393 result["compiler"] = {{"family", "msvc"}, {"version", _MSC_VER}};
18394#elif defined(__PGI)
18395 result["compiler"] = {{"family", "pgcpp"}, {"version", __PGI}};
18396#elif defined(__SUNPRO_CC)
18397 result["compiler"] = {{"family", "sunpro"}, {"version", __SUNPRO_CC}};
18398#else
18399 result["compiler"] = {{"family", "unknown"}, {"version", "unknown"}};
18400#endif
18401
18402
18403#if defined(_MSVC_LANG)
18404 result["compiler"]["c++"] = std::to_string(_MSVC_LANG);
18405#elif defined(__cplusplus)
18406 result["compiler"]["c++"] = std::to_string(__cplusplus);
18407#else
18408 result["compiler"]["c++"] = "unknown";
18409#endif
18410 return result;
18411 }
18412
18413
18415 // JSON value data types //
18417
18422
18427#if defined(JSON_HAS_CPP_14)
18428 // use of transparent comparator avoids unnecessary repeated construction of temporaries
18429 // in functions involving lookup by key with types other than object_t::key_type (aka. StringType)
18430 using default_object_comparator_t = std::less<>;
18431#else
18432 using default_object_comparator_t = std::less<StringType>;
18433#endif
18434
18437 using object_t = ObjectType<StringType,
18438 basic_json,
18440 AllocatorType<std::pair<const StringType,
18441 basic_json>>>;
18442
18445 using array_t = ArrayType<basic_json, AllocatorType<basic_json>>;
18446
18449 using string_t = StringType;
18450
18453 using boolean_t = BooleanType;
18454
18457 using number_integer_t = NumberIntegerType;
18458
18461 using number_unsigned_t = NumberUnsignedType;
18462
18465 using number_float_t = NumberFloatType;
18466
18470
18474
18476
18477 private:
18478
18480 template<typename T, typename... Args>
18482 static T* create(Args&& ... args)
18483 {
18484 AllocatorType<T> alloc;
18485 using AllocatorTraits = std::allocator_traits<AllocatorType<T>>;
18486
18487 auto deleter = [&](T * obj)
18488 {
18489 AllocatorTraits::deallocate(alloc, obj, 1);
18490 };
18491 std::unique_ptr<T, decltype(deleter)> obj(AllocatorTraits::allocate(alloc, 1), deleter);
18492 AllocatorTraits::construct(alloc, obj.get(), std::forward<Args>(args)...);
18493 JSON_ASSERT(obj != nullptr);
18494 return obj.release();
18495 }
18496
18498 // JSON value storage //
18500
18527 union json_value
18528 {
18532 array_t* array;
18538 boolean_t boolean;
18540 number_integer_t number_integer;
18542 number_unsigned_t number_unsigned;
18544 number_float_t number_float;
18545
18547 json_value() = default;
18549 json_value(boolean_t v) noexcept : boolean(v) {}
18551 json_value(number_integer_t v) noexcept : number_integer(v) {}
18553 json_value(number_unsigned_t v) noexcept : number_unsigned(v) {}
18555 json_value(number_float_t v) noexcept : number_float(v) {}
18557 json_value(value_t t)
18558 {
18559 switch (t)
18560 {
18561 case value_t::object:
18562 {
18563 object = create<object_t>();
18564 break;
18565 }
18566
18567 case value_t::array:
18568 {
18569 array = create<array_t>();
18570 break;
18571 }
18572
18573 case value_t::string:
18574 {
18575 string = create<string_t>("");
18576 break;
18577 }
18578
18579 case value_t::binary:
18580 {
18581 binary = create<binary_t>();
18582 break;
18583 }
18584
18585 case value_t::boolean:
18586 {
18587 boolean = static_cast<boolean_t>(false);
18588 break;
18589 }
18590
18591 case value_t::number_integer:
18592 {
18593 number_integer = static_cast<number_integer_t>(0);
18594 break;
18595 }
18596
18597 case value_t::number_unsigned:
18598 {
18599 number_unsigned = static_cast<number_unsigned_t>(0);
18600 break;
18601 }
18602
18603 case value_t::number_float:
18604 {
18605 number_float = static_cast<number_float_t>(0.0);
18606 break;
18607 }
18608
18609 case value_t::null:
18610 {
18611 object = nullptr; // silence warning, see #821
18612 break;
18613 }
18614
18615 case value_t::discarded:
18616 default:
18617 {
18618 object = nullptr; // silence warning, see #821
18619 if (JSON_HEDLEY_UNLIKELY(t == value_t::null))
18620 {
18621 JSON_THROW(other_error::create(500, "961c151d2e87f2686a955a9be24d316f1362bf21 3.10.5", nullptr)); // LCOV_EXCL_LINE
18622 }
18623 break;
18624 }
18625 }
18626 }
18627
18629 json_value(const string_t& value) : string(create<string_t>(value)) {}
18630
18632 json_value(string_t&& value) : string(create<string_t>(std::move(value))) {}
18633
18635 json_value(const object_t& value) : object(create<object_t>(value)) {}
18636
18638 json_value(object_t&& value) : object(create<object_t>(std::move(value))) {}
18639
18641 json_value(const array_t& value) : array(create<array_t>(value)) {}
18642
18644 json_value(array_t&& value) : array(create<array_t>(std::move(value))) {}
18645
18647 json_value(const typename binary_t::container_type& value) : binary(create<binary_t>(value)) {}
18648
18650 json_value(typename binary_t::container_type&& value) : binary(create<binary_t>(std::move(value))) {}
18651
18653 json_value(const binary_t& value) : binary(create<binary_t>(value)) {}
18654
18656 json_value(binary_t&& value) : binary(create<binary_t>(std::move(value))) {}
18657
18658 void destroy(value_t t)
18659 {
18660 if (t == value_t::array || t == value_t::object)
18661 {
18662 // flatten the current json_value to a heap-allocated stack
18663 std::vector<basic_json> stack;
18664
18665 // move the top-level items to stack
18666 if (t == value_t::array)
18667 {
18668 stack.reserve(array->size());
18669 std::move(array->begin(), array->end(), std::back_inserter(stack));
18670 }
18671 else
18672 {
18673 stack.reserve(object->size());
18674 for (auto&& it : *object)
18675 {
18676 stack.push_back(std::move(it.second));
18677 }
18678 }
18679
18680 while (!stack.empty())
18681 {
18682 // move the last item to local variable to be processed
18683 basic_json current_item(std::move(stack.back()));
18684 stack.pop_back();
18685
18686 // if current_item is array/object, move
18687 // its children to the stack to be processed later
18688 if (current_item.is_array())
18689 {
18690 std::move(current_item.m_value.array->begin(), current_item.m_value.array->end(), std::back_inserter(stack));
18691
18692 current_item.m_value.array->clear();
18693 }
18694 else if (current_item.is_object())
18695 {
18696 for (auto&& it : *current_item.m_value.object)
18697 {
18698 stack.push_back(std::move(it.second));
18699 }
18700
18701 current_item.m_value.object->clear();
18702 }
18703
18704 // it's now safe that current_item get destructed
18705 // since it doesn't have any children
18706 }
18707 }
18708
18709 switch (t)
18710 {
18711 case value_t::object:
18712 {
18713 AllocatorType<object_t> alloc;
18714 std::allocator_traits<decltype(alloc)>::destroy(alloc, object);
18715 std::allocator_traits<decltype(alloc)>::deallocate(alloc, object, 1);
18716 break;
18717 }
18718
18719 case value_t::array:
18720 {
18721 AllocatorType<array_t> alloc;
18722 std::allocator_traits<decltype(alloc)>::destroy(alloc, array);
18723 std::allocator_traits<decltype(alloc)>::deallocate(alloc, array, 1);
18724 break;
18725 }
18726
18727 case value_t::string:
18728 {
18729 AllocatorType<string_t> alloc;
18730 std::allocator_traits<decltype(alloc)>::destroy(alloc, string);
18731 std::allocator_traits<decltype(alloc)>::deallocate(alloc, string, 1);
18732 break;
18733 }
18734
18735 case value_t::binary:
18736 {
18737 AllocatorType<binary_t> alloc;
18738 std::allocator_traits<decltype(alloc)>::destroy(alloc, binary);
18739 std::allocator_traits<decltype(alloc)>::deallocate(alloc, binary, 1);
18740 break;
18741 }
18742
18743 case value_t::null:
18744 case value_t::boolean:
18745 case value_t::number_integer:
18746 case value_t::number_unsigned:
18747 case value_t::number_float:
18748 case value_t::discarded:
18749 default:
18750 {
18751 break;
18752 }
18753 }
18754 }
18755 };
18756
18757 private:
18776 void assert_invariant(bool check_parents = true) const noexcept
18777 {
18778 JSON_ASSERT(m_type != value_t::object || m_value.object != nullptr);
18779 JSON_ASSERT(m_type != value_t::array || m_value.array != nullptr);
18780 JSON_ASSERT(m_type != value_t::string || m_value.string != nullptr);
18781 JSON_ASSERT(m_type != value_t::binary || m_value.binary != nullptr);
18782
18783#if JSON_DIAGNOSTICS
18784 JSON_TRY
18785 {
18786 // cppcheck-suppress assertWithSideEffect
18787 JSON_ASSERT(!check_parents || !is_structured() || std::all_of(begin(), end(), [this](const basic_json & j)
18788 {
18789 return j.m_parent == this;
18790 }));
18791 }
18792 JSON_CATCH(...) {} // LCOV_EXCL_LINE
18793#endif
18794 static_cast<void>(check_parents);
18795 }
18796
18797 void set_parents()
18798 {
18799#if JSON_DIAGNOSTICS
18800 switch (m_type)
18801 {
18802 case value_t::array:
18803 {
18804 for (auto& element : *m_value.array)
18805 {
18806 element.m_parent = this;
18807 }
18808 break;
18809 }
18810
18811 case value_t::object:
18812 {
18813 for (auto& element : *m_value.object)
18814 {
18815 element.second.m_parent = this;
18816 }
18817 break;
18818 }
18819
18820 case value_t::null:
18821 case value_t::string:
18822 case value_t::boolean:
18823 case value_t::number_integer:
18824 case value_t::number_unsigned:
18825 case value_t::number_float:
18826 case value_t::binary:
18827 case value_t::discarded:
18828 default:
18829 break;
18830 }
18831#endif
18832 }
18833
18834 iterator set_parents(iterator it, typename iterator::difference_type count_set_parents)
18835 {
18836#if JSON_DIAGNOSTICS
18837 for (typename iterator::difference_type i = 0; i < count_set_parents; ++i)
18838 {
18839 (it + i)->m_parent = this;
18840 }
18841#else
18842 static_cast<void>(count_set_parents);
18843#endif
18844 return it;
18845 }
18846
18847 reference set_parent(reference j, std::size_t old_capacity = static_cast<std::size_t>(-1))
18848 {
18849#if JSON_DIAGNOSTICS
18850 if (old_capacity != static_cast<std::size_t>(-1))
18851 {
18852 // see https://github.com/nlohmann/json/issues/2838
18853 JSON_ASSERT(type() == value_t::array);
18854 if (JSON_HEDLEY_UNLIKELY(m_value.array->capacity() != old_capacity))
18855 {
18856 // capacity has changed: update all parents
18857 set_parents();
18858 return j;
18859 }
18860 }
18861
18862 // ordered_json uses a vector internally, so pointers could have
18863 // been invalidated; see https://github.com/nlohmann/json/issues/2962
18864#ifdef JSON_HEDLEY_MSVC_VERSION
18865#pragma warning(push )
18866#pragma warning(disable : 4127) // ignore warning to replace if with if constexpr
18867#endif
18869 {
18870 set_parents();
18871 return j;
18872 }
18873#ifdef JSON_HEDLEY_MSVC_VERSION
18874#pragma warning( pop )
18875#endif
18876
18877 j.m_parent = this;
18878#else
18879 static_cast<void>(j);
18880 static_cast<void>(old_capacity);
18881#endif
18882 return j;
18883 }
18884
18885 public:
18887 // JSON parser callback //
18889
18892 using parse_event_t = detail::parse_event_t;
18893
18896 using parser_callback_t = detail::parser_callback_t<basic_json>;
18897
18899 // constructors //
18901
18906
18910 : m_type(v), m_value(v)
18911 {
18912 assert_invariant();
18913 }
18914
18917 basic_json(std::nullptr_t = nullptr) noexcept // NOLINT(bugprone-exception-escape)
18918 : basic_json(value_t::null)
18919 {
18920 assert_invariant();
18921 }
18922
18925 template < typename CompatibleType,
18929 basic_json(CompatibleType && val) noexcept(noexcept( // NOLINT(bugprone-forwarding-reference-overload,bugprone-exception-escape)
18930 JSONSerializer<U>::to_json(std::declval<basic_json_t&>(),
18931 std::forward<CompatibleType>(val))))
18932 {
18933 JSONSerializer<U>::to_json(*this, std::forward<CompatibleType>(val));
18934 set_parents();
18935 assert_invariant();
18936 }
18937
18940 template < typename BasicJsonType,
18942 detail::is_basic_json<BasicJsonType>::value&& !std::is_same<basic_json, BasicJsonType>::value, int > = 0 >
18943 basic_json(const BasicJsonType& val)
18944 {
18945 using other_boolean_t = typename BasicJsonType::boolean_t;
18946 using other_number_float_t = typename BasicJsonType::number_float_t;
18947 using other_number_integer_t = typename BasicJsonType::number_integer_t;
18948 using other_number_unsigned_t = typename BasicJsonType::number_unsigned_t;
18949 using other_string_t = typename BasicJsonType::string_t;
18950 using other_object_t = typename BasicJsonType::object_t;
18951 using other_array_t = typename BasicJsonType::array_t;
18952 using other_binary_t = typename BasicJsonType::binary_t;
18953
18954 switch (val.type())
18955 {
18956 case value_t::boolean:
18957 JSONSerializer<other_boolean_t>::to_json(*this, val.template get<other_boolean_t>());
18958 break;
18959 case value_t::number_float:
18960 JSONSerializer<other_number_float_t>::to_json(*this, val.template get<other_number_float_t>());
18961 break;
18962 case value_t::number_integer:
18963 JSONSerializer<other_number_integer_t>::to_json(*this, val.template get<other_number_integer_t>());
18964 break;
18965 case value_t::number_unsigned:
18966 JSONSerializer<other_number_unsigned_t>::to_json(*this, val.template get<other_number_unsigned_t>());
18967 break;
18968 case value_t::string:
18969 JSONSerializer<other_string_t>::to_json(*this, val.template get_ref<const other_string_t&>());
18970 break;
18971 case value_t::object:
18972 JSONSerializer<other_object_t>::to_json(*this, val.template get_ref<const other_object_t&>());
18973 break;
18974 case value_t::array:
18975 JSONSerializer<other_array_t>::to_json(*this, val.template get_ref<const other_array_t&>());
18976 break;
18977 case value_t::binary:
18978 JSONSerializer<other_binary_t>::to_json(*this, val.template get_ref<const other_binary_t&>());
18979 break;
18980 case value_t::null:
18981 *this = nullptr;
18982 break;
18983 case value_t::discarded:
18984 m_type = value_t::discarded;
18985 break;
18986 default: // LCOV_EXCL_LINE
18987 JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert) LCOV_EXCL_LINE
18988 }
18989 set_parents();
18990 assert_invariant();
18991 }
18992
18996 bool type_deduction = true,
18997 value_t manual_type = value_t::array)
18998 {
18999 // check if each element is an array with two elements whose first
19000 // element is a string
19001 bool is_an_object = std::all_of(init.begin(), init.end(),
19002 [](const detail::json_ref<basic_json>& element_ref)
19003 {
19004 return element_ref->is_array() && element_ref->size() == 2 && (*element_ref)[0].is_string();
19005 });
19006
19007 // adjust type if type deduction is not wanted
19008 if (!type_deduction)
19009 {
19010 // if array is wanted, do not create an object though possible
19011 if (manual_type == value_t::array)
19012 {
19013 is_an_object = false;
19014 }
19015
19016 // if object is wanted but impossible, throw an exception
19017 if (JSON_HEDLEY_UNLIKELY(manual_type == value_t::object && !is_an_object))
19018 {
19019 JSON_THROW(type_error::create(301, "cannot create object from initializer list", nullptr));
19020 }
19021 }
19022
19023 if (is_an_object)
19024 {
19025 // the initializer list is a list of pairs -> create object
19026 m_type = value_t::object;
19027 m_value = value_t::object;
19028
19029 for (auto& element_ref : init)
19030 {
19031 auto element = element_ref.moved_or_copied();
19033 std::move(*((*element.m_value.array)[0].m_value.string)),
19034 std::move((*element.m_value.array)[1]));
19035 }
19036 }
19037 else
19038 {
19039 // the initializer list describes an array -> create array
19040 m_type = value_t::array;
19041 m_value.array = create<array_t>(init.begin(), init.end());
19042 }
19043
19044 set_parents();
19045 assert_invariant();
19046 }
19047
19051 static basic_json binary(const typename binary_t::container_type& init)
19052 {
19053 auto res = basic_json();
19054 res.m_type = value_t::binary;
19055 res.m_value = init;
19056 return res;
19057 }
19058
19062 static basic_json binary(const typename binary_t::container_type& init, typename binary_t::subtype_type subtype)
19063 {
19064 auto res = basic_json();
19065 res.m_type = value_t::binary;
19066 res.m_value = binary_t(init, subtype);
19067 return res;
19068 }
19069
19074 {
19075 auto res = basic_json();
19076 res.m_type = value_t::binary;
19077 res.m_value = std::move(init);
19078 return res;
19079 }
19080
19084 static basic_json binary(typename binary_t::container_type&& init, typename binary_t::subtype_type subtype)
19085 {
19086 auto res = basic_json();
19087 res.m_type = value_t::binary;
19088 res.m_value = binary_t(std::move(init), subtype);
19089 return res;
19090 }
19091
19096 {
19097 return basic_json(init, false, value_t::array);
19098 }
19099
19104 {
19105 return basic_json(init, false, value_t::object);
19106 }
19107
19111 : m_type(value_t::array)
19112 {
19113 m_value.array = create<array_t>(cnt, val);
19114 set_parents();
19115 assert_invariant();
19116 }
19117
19120 template < class InputIT, typename std::enable_if <
19121 std::is_same<InputIT, typename basic_json_t::iterator>::value ||
19122 std::is_same<InputIT, typename basic_json_t::const_iterator>::value, int >::type = 0 >
19123 basic_json(InputIT first, InputIT last)
19124 {
19125 JSON_ASSERT(first.m_object != nullptr);
19126 JSON_ASSERT(last.m_object != nullptr);
19127
19128 // make sure iterator fits the current value
19129 if (JSON_HEDLEY_UNLIKELY(first.m_object != last.m_object))
19130 {
19131 JSON_THROW(invalid_iterator::create(201, "iterators are not compatible", nullptr));
19132 }
19133
19134 // copy type from first iterator
19135 m_type = first.m_object->m_type;
19136
19137 // check if iterator range is complete for primitive values
19138 switch (m_type)
19139 {
19140 case value_t::boolean:
19141 case value_t::number_float:
19142 case value_t::number_integer:
19143 case value_t::number_unsigned:
19144 case value_t::string:
19145 {
19146 if (JSON_HEDLEY_UNLIKELY(!first.m_it.primitive_iterator.is_begin()
19147 || !last.m_it.primitive_iterator.is_end()))
19148 {
19149 JSON_THROW(invalid_iterator::create(204, "iterators out of range", first.m_object));
19150 }
19151 break;
19152 }
19153
19154 case value_t::null:
19155 case value_t::object:
19156 case value_t::array:
19157 case value_t::binary:
19158 case value_t::discarded:
19159 default:
19160 break;
19161 }
19162
19163 switch (m_type)
19164 {
19165 case value_t::number_integer:
19166 {
19167 m_value.number_integer = first.m_object->m_value.number_integer;
19168 break;
19169 }
19170
19171 case value_t::number_unsigned:
19172 {
19173 m_value.number_unsigned = first.m_object->m_value.number_unsigned;
19174 break;
19175 }
19176
19177 case value_t::number_float:
19178 {
19179 m_value.number_float = first.m_object->m_value.number_float;
19180 break;
19181 }
19182
19183 case value_t::boolean:
19184 {
19185 m_value.boolean = first.m_object->m_value.boolean;
19186 break;
19187 }
19188
19189 case value_t::string:
19190 {
19191 m_value = *first.m_object->m_value.string;
19192 break;
19193 }
19194
19195 case value_t::object:
19196 {
19197 m_value.object = create<object_t>(first.m_it.object_iterator,
19198 last.m_it.object_iterator);
19199 break;
19200 }
19201
19202 case value_t::array:
19203 {
19204 m_value.array = create<array_t>(first.m_it.array_iterator,
19205 last.m_it.array_iterator);
19206 break;
19207 }
19208
19209 case value_t::binary:
19210 {
19211 m_value = *first.m_object->m_value.binary;
19212 break;
19213 }
19214
19215 case value_t::null:
19216 case value_t::discarded:
19217 default:
19218 JSON_THROW(invalid_iterator::create(206, detail::concat("cannot construct with iterators from ", first.m_object->type_name()), first.m_object));
19219 }
19220
19221 set_parents();
19222 assert_invariant();
19223 }
19224
19225
19227 // other constructors and destructor //
19229
19230 template<typename JsonRef,
19232 std::is_same<typename JsonRef::value_type, basic_json>>::value, int> = 0 >
19233 basic_json(const JsonRef& ref) : basic_json(ref.moved_or_copied()) {}
19234
19238 : m_type(other.m_type)
19239 {
19240 // check of passed value is valid
19241 other.assert_invariant();
19242
19243 switch (m_type)
19244 {
19245 case value_t::object:
19246 {
19247 m_value = *other.m_value.object;
19248 break;
19249 }
19250
19251 case value_t::array:
19252 {
19253 m_value = *other.m_value.array;
19254 break;
19255 }
19256
19257 case value_t::string:
19258 {
19259 m_value = *other.m_value.string;
19260 break;
19261 }
19262
19263 case value_t::boolean:
19264 {
19265 m_value = other.m_value.boolean;
19266 break;
19267 }
19268
19269 case value_t::number_integer:
19270 {
19271 m_value = other.m_value.number_integer;
19272 break;
19273 }
19274
19275 case value_t::number_unsigned:
19276 {
19277 m_value = other.m_value.number_unsigned;
19278 break;
19279 }
19280
19281 case value_t::number_float:
19282 {
19283 m_value = other.m_value.number_float;
19284 break;
19285 }
19286
19287 case value_t::binary:
19288 {
19289 m_value = *other.m_value.binary;
19290 break;
19291 }
19292
19293 case value_t::null:
19294 case value_t::discarded:
19295 default:
19296 break;
19297 }
19298
19299 set_parents();
19300 assert_invariant();
19301 }
19302
19305 basic_json(basic_json&& other) noexcept
19306 : m_type(std::move(other.m_type)),
19307 m_value(std::move(other.m_value))
19308 {
19309 // check that passed value is valid
19310 other.assert_invariant(false);
19311
19312 // invalidate payload
19313 other.m_type = value_t::null;
19314 other.m_value = {};
19315
19316 set_parents();
19317 assert_invariant();
19318 }
19319
19323 std::is_nothrow_move_constructible<value_t>::value&&
19324 std::is_nothrow_move_assignable<value_t>::value&&
19325 std::is_nothrow_move_constructible<json_value>::value&&
19326 std::is_nothrow_move_assignable<json_value>::value
19327 )
19328 {
19329 // check that passed value is valid
19330 other.assert_invariant();
19331
19332 using std::swap;
19333 swap(m_type, other.m_type);
19334 swap(m_value, other.m_value);
19335
19336 set_parents();
19337 assert_invariant();
19338 return *this;
19339 }
19340
19343 ~basic_json() noexcept
19344 {
19345 assert_invariant(false);
19346 m_value.destroy(m_type);
19347 }
19348
19350
19351 public:
19353 // object inspection //
19355
19359
19362 string_t dump(const int indent = -1,
19363 const char indent_char = ' ',
19364 const bool ensure_ascii = false,
19365 const error_handler_t error_handler = error_handler_t::strict) const
19366 {
19368 serializer s(detail::output_adapter<char, string_t>(result), indent_char, error_handler);
19369
19370 if (indent >= 0)
19371 {
19372 s.dump(*this, true, ensure_ascii, static_cast<unsigned int>(indent));
19373 }
19374 else
19375 {
19376 s.dump(*this, false, ensure_ascii, 0);
19377 }
19378
19379 return result;
19380 }
19381
19384 constexpr value_t type() const noexcept
19385 {
19386 return m_type;
19387 }
19388
19391 constexpr bool is_primitive() const noexcept
19392 {
19393 return is_null() || is_string() || is_boolean() || is_number() || is_binary();
19394 }
19395
19398 constexpr bool is_structured() const noexcept
19399 {
19400 return is_array() || is_object();
19401 }
19402
19405 constexpr bool is_null() const noexcept
19406 {
19407 return m_type == value_t::null;
19408 }
19409
19412 constexpr bool is_boolean() const noexcept
19413 {
19414 return m_type == value_t::boolean;
19415 }
19416
19419 constexpr bool is_number() const noexcept
19420 {
19421 return is_number_integer() || is_number_float();
19422 }
19423
19426 constexpr bool is_number_integer() const noexcept
19427 {
19428 return m_type == value_t::number_integer || m_type == value_t::number_unsigned;
19429 }
19430
19433 constexpr bool is_number_unsigned() const noexcept
19434 {
19435 return m_type == value_t::number_unsigned;
19436 }
19437
19440 constexpr bool is_number_float() const noexcept
19441 {
19442 return m_type == value_t::number_float;
19443 }
19444
19447 constexpr bool is_object() const noexcept
19448 {
19449 return m_type == value_t::object;
19450 }
19451
19454 constexpr bool is_array() const noexcept
19455 {
19456 return m_type == value_t::array;
19457 }
19458
19461 constexpr bool is_string() const noexcept
19462 {
19463 return m_type == value_t::string;
19464 }
19465
19468 constexpr bool is_binary() const noexcept
19469 {
19470 return m_type == value_t::binary;
19471 }
19472
19475 constexpr bool is_discarded() const noexcept
19476 {
19477 return m_type == value_t::discarded;
19478 }
19479
19482 constexpr operator value_t() const noexcept
19483 {
19484 return m_type;
19485 }
19486
19488
19489 private:
19491 // value access //
19493
19495 boolean_t get_impl(boolean_t* /*unused*/) const
19496 {
19498 {
19499 return m_value.boolean;
19500 }
19501
19502 JSON_THROW(type_error::create(302, detail::concat("type must be boolean, but is ", type_name()), this));
19503 }
19504
19506 object_t* get_impl_ptr(object_t* /*unused*/) noexcept
19507 {
19508 return is_object() ? m_value.object : nullptr;
19509 }
19510
19512 constexpr const object_t* get_impl_ptr(const object_t* /*unused*/) const noexcept
19513 {
19514 return is_object() ? m_value.object : nullptr;
19515 }
19516
19518 array_t* get_impl_ptr(array_t* /*unused*/) noexcept
19519 {
19520 return is_array() ? m_value.array : nullptr;
19521 }
19522
19524 constexpr const array_t* get_impl_ptr(const array_t* /*unused*/) const noexcept
19525 {
19526 return is_array() ? m_value.array : nullptr;
19527 }
19528
19530 string_t* get_impl_ptr(string_t* /*unused*/) noexcept
19531 {
19532 return is_string() ? m_value.string : nullptr;
19533 }
19534
19536 constexpr const string_t* get_impl_ptr(const string_t* /*unused*/) const noexcept
19537 {
19538 return is_string() ? m_value.string : nullptr;
19539 }
19540
19542 boolean_t* get_impl_ptr(boolean_t* /*unused*/) noexcept
19543 {
19544 return is_boolean() ? &m_value.boolean : nullptr;
19545 }
19546
19548 constexpr const boolean_t* get_impl_ptr(const boolean_t* /*unused*/) const noexcept
19549 {
19550 return is_boolean() ? &m_value.boolean : nullptr;
19551 }
19552
19554 number_integer_t* get_impl_ptr(number_integer_t* /*unused*/) noexcept
19555 {
19556 return is_number_integer() ? &m_value.number_integer : nullptr;
19557 }
19558
19560 constexpr const number_integer_t* get_impl_ptr(const number_integer_t* /*unused*/) const noexcept
19561 {
19562 return is_number_integer() ? &m_value.number_integer : nullptr;
19563 }
19564
19566 number_unsigned_t* get_impl_ptr(number_unsigned_t* /*unused*/) noexcept
19567 {
19568 return is_number_unsigned() ? &m_value.number_unsigned : nullptr;
19569 }
19570
19572 constexpr const number_unsigned_t* get_impl_ptr(const number_unsigned_t* /*unused*/) const noexcept
19573 {
19574 return is_number_unsigned() ? &m_value.number_unsigned : nullptr;
19575 }
19576
19578 number_float_t* get_impl_ptr(number_float_t* /*unused*/) noexcept
19579 {
19580 return is_number_float() ? &m_value.number_float : nullptr;
19581 }
19582
19584 constexpr const number_float_t* get_impl_ptr(const number_float_t* /*unused*/) const noexcept
19585 {
19586 return is_number_float() ? &m_value.number_float : nullptr;
19587 }
19588
19590 binary_t* get_impl_ptr(binary_t* /*unused*/) noexcept
19591 {
19592 return is_binary() ? m_value.binary : nullptr;
19593 }
19594
19596 constexpr const binary_t* get_impl_ptr(const binary_t* /*unused*/) const noexcept
19597 {
19598 return is_binary() ? m_value.binary : nullptr;
19599 }
19600
19612 template<typename ReferenceType, typename ThisType>
19613 static ReferenceType get_ref_impl(ThisType& obj)
19614 {
19615 // delegate the call to get_ptr<>()
19616 auto* ptr = obj.template get_ptr<typename std::add_pointer<ReferenceType>::type>();
19617
19618 if (JSON_HEDLEY_LIKELY(ptr != nullptr))
19619 {
19620 return *ptr;
19621 }
19622
19623 JSON_THROW(type_error::create(303, detail::concat("incompatible ReferenceType for get_ref, actual type is ", obj.type_name()), &obj));
19624 }
19625
19626 public:
19630
19633 template<typename PointerType, typename std::enable_if<
19634 std::is_pointer<PointerType>::value, int>::type = 0>
19635 auto get_ptr() noexcept -> decltype(std::declval<basic_json_t&>().get_impl_ptr(std::declval<PointerType>()))
19636 {
19637 // delegate the call to get_impl_ptr<>()
19638 return get_impl_ptr(static_cast<PointerType>(nullptr));
19639 }
19640
19643 template < typename PointerType, typename std::enable_if <
19644 std::is_pointer<PointerType>::value&&
19645 std::is_const<typename std::remove_pointer<PointerType>::type>::value, int >::type = 0 >
19646 constexpr auto get_ptr() const noexcept -> decltype(std::declval<const basic_json_t&>().get_impl_ptr(std::declval<PointerType>()))
19647 {
19648 // delegate the call to get_impl_ptr<>() const
19649 return get_impl_ptr(static_cast<PointerType>(nullptr));
19650 }
19651
19652 private:
19691 template < typename ValueType,
19695 int > = 0 >
19696 ValueType get_impl(detail::priority_tag<0> /*unused*/) const noexcept(noexcept(
19697 JSONSerializer<ValueType>::from_json(std::declval<const basic_json_t&>(), std::declval<ValueType&>())))
19698 {
19699 auto ret = ValueType();
19700 JSONSerializer<ValueType>::from_json(*this, ret);
19701 return ret;
19702 }
19703
19734 template < typename ValueType,
19736 detail::has_non_default_from_json<basic_json_t, ValueType>::value,
19737 int > = 0 >
19738 ValueType get_impl(detail::priority_tag<1> /*unused*/) const noexcept(noexcept(
19739 JSONSerializer<ValueType>::from_json(std::declval<const basic_json_t&>())))
19740 {
19741 return JSONSerializer<ValueType>::from_json(*this);
19742 }
19743
19759 template < typename BasicJsonType,
19761 detail::is_basic_json<BasicJsonType>::value,
19762 int > = 0 >
19763 BasicJsonType get_impl(detail::priority_tag<2> /*unused*/) const
19764 {
19765 return *this;
19766 }
19767
19782 template<typename BasicJsonType,
19784 std::is_same<BasicJsonType, basic_json_t>::value,
19785 int> = 0>
19786 basic_json get_impl(detail::priority_tag<3> /*unused*/) const
19787 {
19788 return *this;
19789 }
19790
19795 template<typename PointerType,
19797 std::is_pointer<PointerType>::value,
19798 int> = 0>
19799 constexpr auto get_impl(detail::priority_tag<4> /*unused*/) const noexcept
19800 -> decltype(std::declval<const basic_json_t&>().template get_ptr<PointerType>())
19801 {
19802 // delegate the call to get_ptr
19803 return get_ptr<PointerType>();
19804 }
19805
19806 public:
19830 template < typename ValueTypeCV, typename ValueType = detail::uncvref_t<ValueTypeCV>>
19831#if defined(JSON_HAS_CPP_14)
19832 constexpr
19833#endif
19834 auto get() const noexcept(
19835 noexcept(std::declval<const basic_json_t&>().template get_impl<ValueType>(detail::priority_tag<4> {})))
19836 -> decltype(std::declval<const basic_json_t&>().template get_impl<ValueType>(detail::priority_tag<4> {}))
19837 {
19838 // we cannot static_assert on ValueTypeCV being non-const, because
19839 // there is support for get<const basic_json_t>(), which is why we
19840 // still need the uncvref
19841 static_assert(!std::is_reference<ValueTypeCV>::value,
19842 "get() cannot be used with reference types, you might want to use get_ref()");
19843 return get_impl<ValueType>(detail::priority_tag<4> {});
19844 }
19845
19873 template<typename PointerType, typename std::enable_if<
19874 std::is_pointer<PointerType>::value, int>::type = 0>
19875 auto get() noexcept -> decltype(std::declval<basic_json_t&>().template get_ptr<PointerType>())
19876 {
19877 // delegate the call to get_ptr
19878 return get_ptr<PointerType>();
19879 }
19880
19883 template < typename ValueType,
19887 int > = 0 >
19888 ValueType & get_to(ValueType& v) const noexcept(noexcept(
19889 JSONSerializer<ValueType>::from_json(std::declval<const basic_json_t&>(), v)))
19890 {
19891 JSONSerializer<ValueType>::from_json(*this, v);
19892 return v;
19893 }
19894
19895 // specialization to allow calling get_to with a basic_json value
19896 // see https://github.com/nlohmann/json/issues/2175
19897 template<typename ValueType,
19900 int> = 0>
19901 ValueType & get_to(ValueType& v) const
19902 {
19903 v = *this;
19904 return v;
19905 }
19906
19907 template <
19908 typename T, std::size_t N,
19909 typename Array = T (&)[N], // NOLINT(cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays)
19912 Array get_to(T (&v)[N]) const // NOLINT(cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays)
19913 noexcept(noexcept(JSONSerializer<Array>::from_json(
19914 std::declval<const basic_json_t&>(), v)))
19915 {
19916 JSONSerializer<Array>::from_json(*this, v);
19917 return v;
19918 }
19919
19922 template<typename ReferenceType, typename std::enable_if<
19923 std::is_reference<ReferenceType>::value, int>::type = 0>
19924 ReferenceType get_ref()
19925 {
19926 // delegate call to get_ref_impl
19927 return get_ref_impl<ReferenceType>(*this);
19928 }
19929
19932 template < typename ReferenceType, typename std::enable_if <
19933 std::is_reference<ReferenceType>::value&&
19934 std::is_const<typename std::remove_reference<ReferenceType>::type>::value, int >::type = 0 >
19935 ReferenceType get_ref() const
19936 {
19937 // delegate call to get_ref_impl
19938 return get_ref_impl<ReferenceType>(*this);
19939 }
19940
19970 template < typename ValueType, typename std::enable_if <
19978
19979#if defined(JSON_HAS_CPP_17) && (defined(__GNUC__) || (defined(_MSC_VER) && _MSC_VER >= 1910 && _MSC_VER <= 1914))
19981#endif
19982#if defined(JSON_HAS_CPP_17)
19984#endif
19986 >::value, int >::type = 0 >
19987 JSON_EXPLICIT operator ValueType() const
19988 {
19989 // delegate the call to get<>() const
19990 return get<ValueType>();
19991 }
19992
19996 {
19997 if (!is_binary())
19998 {
19999 JSON_THROW(type_error::create(302, detail::concat("type must be binary, but is ", type_name()), this));
20000 }
20001
20002 return *get_ptr<binary_t*>();
20003 }
20004
20007 const binary_t& get_binary() const
20008 {
20009 if (!is_binary())
20010 {
20011 JSON_THROW(type_error::create(302, detail::concat("type must be binary, but is ", type_name()), this));
20012 }
20013
20014 return *get_ptr<const binary_t*>();
20015 }
20016
20018
20019
20021 // element access //
20023
20027
20031 {
20032 // at only works for arrays
20034 {
20035 JSON_TRY
20036 {
20037 return set_parent(m_value.array->at(idx));
20038 }
20039 JSON_CATCH (std::out_of_range&)
20040 {
20041 // create better exception explanation
20042 JSON_THROW(out_of_range::create(401, detail::concat("array index ", std::to_string(idx), " is out of range"), this));
20043 }
20044 }
20045 else
20046 {
20047 JSON_THROW(type_error::create(304, detail::concat("cannot use at() with ", type_name()), this));
20048 }
20049 }
20050
20054 {
20055 // at only works for arrays
20057 {
20058 JSON_TRY
20059 {
20060 return m_value.array->at(idx);
20061 }
20062 JSON_CATCH (std::out_of_range&)
20063 {
20064 // create better exception explanation
20065 JSON_THROW(out_of_range::create(401, detail::concat("array index ", std::to_string(idx), " is out of range"), this));
20066 }
20067 }
20068 else
20069 {
20070 JSON_THROW(type_error::create(304, detail::concat("cannot use at() with ", type_name()), this));
20071 }
20072 }
20073
20076 reference at(const typename object_t::key_type& key)
20077 {
20078 // at only works for objects
20080 {
20081 JSON_THROW(type_error::create(304, detail::concat("cannot use at() with ", type_name()), this));
20082 }
20083
20084 auto it = m_value.object->find(key);
20085 if (it == m_value.object->end())
20086 {
20087 JSON_THROW(out_of_range::create(403, detail::concat("key '", key, "' not found"), this));
20088 }
20089 return set_parent(it->second);
20090 }
20091
20094 template<class KeyType, detail::enable_if_t<
20096 reference at(KeyType && key)
20097 {
20098 // at only works for objects
20100 {
20101 JSON_THROW(type_error::create(304, detail::concat("cannot use at() with ", type_name()), this));
20102 }
20103
20104 auto it = m_value.object->find(std::forward<KeyType>(key));
20105 if (it == m_value.object->end())
20106 {
20107 JSON_THROW(out_of_range::create(403, detail::concat("key '", string_t(std::forward<KeyType>(key)), "' not found"), this));
20108 }
20109 return set_parent(it->second);
20110 }
20111
20114 const_reference at(const typename object_t::key_type& key) const
20115 {
20116 // at only works for objects
20118 {
20119 JSON_THROW(type_error::create(304, detail::concat("cannot use at() with ", type_name()), this));
20120 }
20121
20122 auto it = m_value.object->find(key);
20123 if (it == m_value.object->end())
20124 {
20125 JSON_THROW(out_of_range::create(403, detail::concat("key '", key, "' not found"), this));
20126 }
20127 return it->second;
20128 }
20129
20132 template<class KeyType, detail::enable_if_t<
20134 const_reference at(KeyType && key) const
20135 {
20136 // at only works for objects
20138 {
20139 JSON_THROW(type_error::create(304, detail::concat("cannot use at() with ", type_name()), this));
20140 }
20141
20142 auto it = m_value.object->find(std::forward<KeyType>(key));
20143 if (it == m_value.object->end())
20144 {
20145 JSON_THROW(out_of_range::create(403, detail::concat("key '", string_t(std::forward<KeyType>(key)), "' not found"), this));
20146 }
20147 return it->second;
20148 }
20149
20153 {
20154 // implicitly convert null value to an empty array
20155 if (is_null())
20156 {
20157 m_type = value_t::array;
20158 m_value.array = create<array_t>();
20159 assert_invariant();
20160 }
20161
20162 // operator[] only works for arrays
20164 {
20165 // fill up array with null values if given idx is outside range
20166 if (idx >= m_value.array->size())
20167 {
20168#if JSON_DIAGNOSTICS
20169 // remember array size & capacity before resizing
20170 const auto old_size = m_value.array->size();
20171 const auto old_capacity = m_value.array->capacity();
20172#endif
20173 m_value.array->resize(idx + 1);
20174
20175#if JSON_DIAGNOSTICS
20176 if (JSON_HEDLEY_UNLIKELY(m_value.array->capacity() != old_capacity))
20177 {
20178 // capacity has changed: update all parents
20179 set_parents();
20180 }
20181 else
20182 {
20183 // set parent for values added above
20184 set_parents(begin() + static_cast<typename iterator::difference_type>(old_size), static_cast<typename iterator::difference_type>(idx + 1 - old_size));
20185 }
20186#endif
20187 assert_invariant();
20188 }
20189
20190 return m_value.array->operator[](idx);
20191 }
20192
20193 JSON_THROW(type_error::create(305, detail::concat("cannot use operator[] with a numeric argument with ", type_name()), this));
20194 }
20195
20199 {
20200 // const operator[] only works for arrays
20202 {
20203 return m_value.array->operator[](idx);
20204 }
20205
20206 JSON_THROW(type_error::create(305, detail::concat("cannot use operator[] with a numeric argument with ", type_name()), this));
20207 }
20208
20211 reference operator[](typename object_t::key_type key)
20212 {
20213 // implicitly convert null value to an empty object
20214 if (is_null())
20215 {
20216 m_type = value_t::object;
20217 m_value.object = create<object_t>();
20218 assert_invariant();
20219 }
20220
20221 // operator[] only works for objects
20223 {
20224 auto result = m_value.object->emplace(std::move(key), nullptr);
20225 return set_parent(result.first->second);
20226 }
20227
20228 JSON_THROW(type_error::create(305, detail::concat("cannot use operator[] with a string argument with ", type_name()), this));
20229 }
20230
20233 const_reference operator[](const typename object_t::key_type& key) const
20234 {
20235 // const operator[] only works for objects
20237 {
20238 auto it = m_value.object->find(key);
20239 JSON_ASSERT(it != m_value.object->end());
20240 return it->second;
20241 }
20242
20243 JSON_THROW(type_error::create(305, detail::concat("cannot use operator[] with a string argument with ", type_name()), this));
20244 }
20245
20246 // these two functions resolve a (const) char * ambiguity affecting Clang and MSVC
20247 // (they seemingly cannot be constrained to resolve the ambiguity)
20248 template<typename T>
20250 {
20251 return operator[](typename object_t::key_type(key));
20252 }
20253
20254 template<typename T>
20256 {
20257 return operator[](typename object_t::key_type(key));
20258 }
20259
20262 template<class KeyType, detail::enable_if_t<
20264 reference operator[](KeyType && key)
20265 {
20266 // implicitly convert null value to an empty object
20267 if (is_null())
20268 {
20269 m_type = value_t::object;
20270 m_value.object = create<object_t>();
20271 assert_invariant();
20272 }
20273
20274 // operator[] only works for objects
20276 {
20277 auto result = m_value.object->emplace(std::forward<KeyType>(key), nullptr);
20278 return set_parent(result.first->second);
20279 }
20280
20281 JSON_THROW(type_error::create(305, detail::concat("cannot use operator[] with a string argument with ", type_name()), this));
20282 }
20283
20286 template<class KeyType, detail::enable_if_t<
20288 const_reference operator[](KeyType && key) const
20289 {
20290 // const operator[] only works for objects
20292 {
20293 auto it = m_value.object->find(std::forward<KeyType>(key));
20294 JSON_ASSERT(it != m_value.object->end());
20295 return it->second;
20296 }
20297
20298 JSON_THROW(type_error::create(305, detail::concat("cannot use operator[] with a string argument with ", type_name()), this));
20299 }
20300
20303 // this is the value(const typename object_t::key_type&) overload
20304 template < class KeyType, class ValueType, detail::enable_if_t <
20305 std::is_same<KeyType, typename object_t::key_type>::value
20307 && !std::is_same<value_t, ValueType>::value, int > = 0 >
20308 typename std::decay<ValueType>::type value(const KeyType& key, ValueType && default_value) const
20309 {
20310 // value only works for objects
20312 {
20313 // if key is found, return value and given default value otherwise
20314 const auto it = find(key);
20315 if (it != end())
20316 {
20317 return it->template get<typename std::decay<ValueType>::type>();
20318 }
20319
20320 return std::forward<ValueType>(default_value);
20321 }
20322
20323 JSON_THROW(type_error::create(306, detail::concat("cannot use value() with ", type_name()), this));
20324 }
20325
20329 string_t value(const typename object_t::key_type& key, const char* default_value) const
20330 {
20331 return value(key, string_t(default_value));
20332 }
20333
20334 // these two functions, in conjunction with value(const KeyType &, ValueType &&),
20335 // resolve an ambiguity that would otherwise occur between the json_pointer and
20336 // typename object_t::key_type & overloads
20337 template < class ValueType, detail::enable_if_t <
20339 && !std::is_same<value_t, ValueType>::value, int > = 0 >
20340 typename std::decay<ValueType>::type value(const char* key, ValueType && default_value) const
20341 {
20342 return value(typename object_t::key_type(key), std::forward<ValueType>(default_value));
20343 }
20344
20345 string_t value(const char* key, const char* default_value) const
20346 {
20347 return value(typename object_t::key_type(key), string_t(default_value));
20348 }
20349
20353 template < class KeyType, class ValueType, detail::enable_if_t <
20355 && !std::is_same<value_t, ValueType>::value
20357 typename std::decay<ValueType>::type value(KeyType && key, ValueType && default_value) const
20358 {
20359 // value only works for objects
20361 {
20362 // if key is found, return value and given default value otherwise
20363 const auto it = find(std::forward<KeyType>(key));
20364 if (it != end())
20365 {
20366 return it->template get<typename std::decay<ValueType>::type>();
20367 }
20368
20369 return std::forward<ValueType>(default_value);
20370 }
20371
20372 JSON_THROW(type_error::create(306, detail::concat("cannot use value() with ", type_name()), this));
20373 }
20374
20378 template < class KeyType, detail::enable_if_t <
20380 string_t value(KeyType && key, const char* default_value) const
20381 {
20382 return value(std::forward<KeyType>(key), string_t(default_value));
20383 }
20384
20387 template < class ValueType, detail::enable_if_t <
20389 ValueType value(const json_pointer& ptr, const ValueType& default_value) const
20390 {
20391 // value only works for objects
20393 {
20394 // if pointer resolves a value, return it or use default value
20395 JSON_TRY
20396 {
20397 return ptr.get_checked(this).template get<ValueType>();
20398 }
20400 {
20401 return default_value;
20402 }
20403 }
20404
20405 JSON_THROW(type_error::create(306, detail::concat("cannot use value() with ", type_name()), this));
20406 }
20407
20408 template < class ValueType, class BasicJsonType, detail::enable_if_t <
20411 ValueType value(const ::nlohmann::json_pointer<BasicJsonType>& ptr, const ValueType& default_value) const
20412 {
20413 return value(ptr.convert(), default_value);
20414 }
20415
20420 string_t value(const json_pointer& ptr, const char* default_value) const
20421 {
20422 return value(ptr, string_t(default_value));
20423 }
20424
20425 template<typename BasicJsonType>
20428 string_t value(const typename ::nlohmann::json_pointer<BasicJsonType>& ptr, const char* default_value) const
20429 {
20430 return value(ptr.convert(), default_value);
20431 }
20432
20436 {
20437 return *begin();
20438 }
20439
20443 {
20444 return *cbegin();
20445 }
20446
20450 {
20451 auto tmp = end();
20452 --tmp;
20453 return *tmp;
20454 }
20455
20459 {
20460 auto tmp = cend();
20461 --tmp;
20462 return *tmp;
20463 }
20464
20467 template < class IteratorType, detail::enable_if_t <
20468 std::is_same<IteratorType, typename basic_json_t::iterator>::value ||
20469 std::is_same<IteratorType, typename basic_json_t::const_iterator>::value, int > = 0 >
20470 IteratorType erase(IteratorType pos)
20471 {
20472 // make sure iterator fits the current value
20473 if (JSON_HEDLEY_UNLIKELY(this != pos.m_object))
20474 {
20475 JSON_THROW(invalid_iterator::create(202, "iterator does not fit current value", this));
20476 }
20477
20478 IteratorType result = end();
20479
20480 switch (m_type)
20481 {
20482 case value_t::boolean:
20483 case value_t::number_float:
20484 case value_t::number_integer:
20485 case value_t::number_unsigned:
20486 case value_t::string:
20487 case value_t::binary:
20488 {
20489 if (JSON_HEDLEY_UNLIKELY(!pos.m_it.primitive_iterator.is_begin()))
20490 {
20491 JSON_THROW(invalid_iterator::create(205, "iterator out of range", this));
20492 }
20493
20494 if (is_string())
20495 {
20496 AllocatorType<string_t> alloc;
20497 std::allocator_traits<decltype(alloc)>::destroy(alloc, m_value.string);
20498 std::allocator_traits<decltype(alloc)>::deallocate(alloc, m_value.string, 1);
20499 m_value.string = nullptr;
20500 }
20501 else if (is_binary())
20502 {
20503 AllocatorType<binary_t> alloc;
20504 std::allocator_traits<decltype(alloc)>::destroy(alloc, m_value.binary);
20505 std::allocator_traits<decltype(alloc)>::deallocate(alloc, m_value.binary, 1);
20506 m_value.binary = nullptr;
20507 }
20508
20509 m_type = value_t::null;
20510 assert_invariant();
20511 break;
20512 }
20513
20514 case value_t::object:
20515 {
20516 result.m_it.object_iterator = m_value.object->erase(pos.m_it.object_iterator);
20517 break;
20518 }
20519
20520 case value_t::array:
20521 {
20522 result.m_it.array_iterator = m_value.array->erase(pos.m_it.array_iterator);
20523 break;
20524 }
20525
20526 case value_t::null:
20527 case value_t::discarded:
20528 default:
20529 JSON_THROW(type_error::create(307, detail::concat("cannot use erase() with ", type_name()), this));
20530 }
20531
20532 return result;
20533 }
20534
20537 template < class IteratorType, detail::enable_if_t <
20538 std::is_same<IteratorType, typename basic_json_t::iterator>::value ||
20539 std::is_same<IteratorType, typename basic_json_t::const_iterator>::value, int > = 0 >
20540 IteratorType erase(IteratorType first, IteratorType last)
20541 {
20542 // make sure iterator fits the current value
20543 if (JSON_HEDLEY_UNLIKELY(this != first.m_object || this != last.m_object))
20544 {
20545 JSON_THROW(invalid_iterator::create(203, "iterators do not fit current value", this));
20546 }
20547
20548 IteratorType result = end();
20549
20550 switch (m_type)
20551 {
20552 case value_t::boolean:
20553 case value_t::number_float:
20554 case value_t::number_integer:
20555 case value_t::number_unsigned:
20556 case value_t::string:
20557 case value_t::binary:
20558 {
20559 if (JSON_HEDLEY_LIKELY(!first.m_it.primitive_iterator.is_begin()
20560 || !last.m_it.primitive_iterator.is_end()))
20561 {
20562 JSON_THROW(invalid_iterator::create(204, "iterators out of range", this));
20563 }
20564
20565 if (is_string())
20566 {
20567 AllocatorType<string_t> alloc;
20568 std::allocator_traits<decltype(alloc)>::destroy(alloc, m_value.string);
20569 std::allocator_traits<decltype(alloc)>::deallocate(alloc, m_value.string, 1);
20570 m_value.string = nullptr;
20571 }
20572 else if (is_binary())
20573 {
20574 AllocatorType<binary_t> alloc;
20575 std::allocator_traits<decltype(alloc)>::destroy(alloc, m_value.binary);
20576 std::allocator_traits<decltype(alloc)>::deallocate(alloc, m_value.binary, 1);
20577 m_value.binary = nullptr;
20578 }
20579
20580 m_type = value_t::null;
20581 assert_invariant();
20582 break;
20583 }
20584
20585 case value_t::object:
20586 {
20587 result.m_it.object_iterator = m_value.object->erase(first.m_it.object_iterator,
20588 last.m_it.object_iterator);
20589 break;
20590 }
20591
20592 case value_t::array:
20593 {
20594 result.m_it.array_iterator = m_value.array->erase(first.m_it.array_iterator,
20595 last.m_it.array_iterator);
20596 break;
20597 }
20598
20599 case value_t::null:
20600 case value_t::discarded:
20601 default:
20602 JSON_THROW(type_error::create(307, detail::concat("cannot use erase() with ", type_name()), this));
20603 }
20604
20605 return result;
20606 }
20607
20608 private:
20609 template < typename KeyType, detail::enable_if_t <
20611 size_type erase_internal(KeyType && key)
20612 {
20613 // this erase only works for objects
20615 {
20616 JSON_THROW(type_error::create(307, detail::concat("cannot use erase() with ", type_name()), this));
20617 }
20618
20619 return m_value.object->erase(std::forward<KeyType>(key));
20620 }
20621
20622 template < typename KeyType, detail::enable_if_t <
20623 !detail::has_erase_with_key_type<basic_json_t, KeyType>::value, int > = 0 >
20624 size_type erase_internal(KeyType && key)
20625 {
20626 // this erase only works for objects
20628 {
20629 JSON_THROW(type_error::create(307, detail::concat("cannot use erase() with ", type_name()), this));
20630 }
20631
20632 const auto it = m_value.object->find(std::forward<KeyType>(key));
20633 if (it != m_value.object->end())
20634 {
20635 m_value.object->erase(it);
20636 return 1;
20637 }
20638 return 0;
20639 }
20640
20641 public:
20642
20645 size_type erase(const typename object_t::key_type& key)
20646 {
20647 // the indirection via erase_internal() is added to avoid making this
20648 // function a template and thus de-rank it during overload resolution
20649 return erase_internal(key);
20650 }
20651
20654 template<class KeyType, detail::enable_if_t<
20656 size_type erase(KeyType && key)
20657 {
20658 return erase_internal(std::forward<KeyType>(key));
20659 }
20660
20663 void erase(const size_type idx)
20664 {
20665 // this erase only works for arrays
20667 {
20668 if (JSON_HEDLEY_UNLIKELY(idx >= size()))
20669 {
20670 JSON_THROW(out_of_range::create(401, detail::concat("array index ", std::to_string(idx), " is out of range"), this));
20671 }
20672
20673 m_value.array->erase(m_value.array->begin() + static_cast<difference_type>(idx));
20674 }
20675 else
20676 {
20677 JSON_THROW(type_error::create(307, detail::concat("cannot use erase() with ", type_name()), this));
20678 }
20679 }
20680
20682
20683
20685 // lookup //
20687
20690
20693 iterator find(const typename object_t::key_type& key)
20694 {
20695 auto result = end();
20696
20697 if (is_object())
20698 {
20699 result.m_it.object_iterator = m_value.object->find(key);
20700 }
20701
20702 return result;
20703 }
20704
20707 const_iterator find(const typename object_t::key_type& key) const
20708 {
20709 auto result = cend();
20710
20711 if (is_object())
20712 {
20713 result.m_it.object_iterator = m_value.object->find(key);
20714 }
20715
20716 return result;
20717 }
20718
20721 template<class KeyType, detail::enable_if_t<
20723 iterator find(KeyType && key)
20724 {
20725 auto result = end();
20726
20727 if (is_object())
20728 {
20729 result.m_it.object_iterator = m_value.object->find(std::forward<KeyType>(key));
20730 }
20731
20732 return result;
20733 }
20734
20737 template<class KeyType, detail::enable_if_t<
20739 const_iterator find(KeyType && key) const
20740 {
20741 auto result = cend();
20742
20743 if (is_object())
20744 {
20745 result.m_it.object_iterator = m_value.object->find(std::forward<KeyType>(key));
20746 }
20747
20748 return result;
20749 }
20750
20753 size_type count(const typename object_t::key_type& key) const
20754 {
20755 // return 0 for all nonobject types
20756 return is_object() ? m_value.object->count(key) : 0;
20757 }
20758
20761 template<class KeyType, detail::enable_if_t<
20763 size_type count(KeyType && key) const
20764 {
20765 // return 0 for all nonobject types
20766 return is_object() ? m_value.object->count(std::forward<KeyType>(key)) : 0;
20767 }
20768
20771 bool contains(const typename object_t::key_type& key) const
20772 {
20773 return is_object() && m_value.object->find(key) != m_value.object->end();
20774 }
20775
20778 template<class KeyType, detail::enable_if_t<
20780 bool contains(KeyType && key) const
20781 {
20782 return is_object() && m_value.object->find(std::forward<KeyType>(key)) != m_value.object->end();
20783 }
20784
20787 bool contains(const json_pointer& ptr) const
20788 {
20789 return ptr.contains(this);
20790 }
20791
20792 template<typename BasicJsonType>
20794 bool contains(const typename ::nlohmann::json_pointer<BasicJsonType> ptr) const
20795 {
20796 return ptr.contains(this);
20797 }
20798
20800
20801
20803 // iterators //
20805
20808
20811 iterator begin() noexcept
20812 {
20813 iterator result(this);
20814 result.set_begin();
20815 return result;
20816 }
20817
20820 const_iterator begin() const noexcept
20821 {
20822 return cbegin();
20823 }
20824
20827 const_iterator cbegin() const noexcept
20828 {
20829 const_iterator result(this);
20830 result.set_begin();
20831 return result;
20832 }
20833
20836 iterator end() noexcept
20837 {
20838 iterator result(this);
20839 result.set_end();
20840 return result;
20841 }
20842
20845 const_iterator end() const noexcept
20846 {
20847 return cend();
20848 }
20849
20852 const_iterator cend() const noexcept
20853 {
20854 const_iterator result(this);
20855 result.set_end();
20856 return result;
20857 }
20858
20862 {
20863 return reverse_iterator(end());
20864 }
20865
20869 {
20870 return crbegin();
20871 }
20872
20876 {
20877 return reverse_iterator(begin());
20878 }
20879
20883 {
20884 return crend();
20885 }
20886
20890 {
20891 return const_reverse_iterator(cend());
20892 }
20893
20897 {
20899 }
20900
20901 public:
20908 static iteration_proxy<iterator> iterator_wrapper(reference ref) noexcept
20909 {
20910 return ref.items();
20911 }
20912
20919 static iteration_proxy<const_iterator> iterator_wrapper(const_reference ref) noexcept
20920 {
20921 return ref.items();
20922 }
20923
20926 iteration_proxy<iterator> items() noexcept
20927 {
20928 return iteration_proxy<iterator>(*this);
20929 }
20930
20933 iteration_proxy<const_iterator> items() const noexcept
20934 {
20935 return iteration_proxy<const_iterator>(*this);
20936 }
20937
20939
20940
20942 // capacity //
20944
20947
20950 bool empty() const noexcept
20951 {
20952 switch (m_type)
20953 {
20954 case value_t::null:
20955 {
20956 // null values are empty
20957 return true;
20958 }
20959
20960 case value_t::array:
20961 {
20962 // delegate call to array_t::empty()
20963 return m_value.array->empty();
20964 }
20965
20966 case value_t::object:
20967 {
20968 // delegate call to object_t::empty()
20969 return m_value.object->empty();
20970 }
20971
20972 case value_t::string:
20973 case value_t::boolean:
20974 case value_t::number_integer:
20975 case value_t::number_unsigned:
20976 case value_t::number_float:
20977 case value_t::binary:
20978 case value_t::discarded:
20979 default:
20980 {
20981 // all other types are nonempty
20982 return false;
20983 }
20984 }
20985 }
20986
20989 size_type size() const noexcept
20990 {
20991 switch (m_type)
20992 {
20993 case value_t::null:
20994 {
20995 // null values are empty
20996 return 0;
20997 }
20998
20999 case value_t::array:
21000 {
21001 // delegate call to array_t::size()
21002 return m_value.array->size();
21003 }
21004
21005 case value_t::object:
21006 {
21007 // delegate call to object_t::size()
21008 return m_value.object->size();
21009 }
21010
21011 case value_t::string:
21012 case value_t::boolean:
21013 case value_t::number_integer:
21014 case value_t::number_unsigned:
21015 case value_t::number_float:
21016 case value_t::binary:
21017 case value_t::discarded:
21018 default:
21019 {
21020 // all other types have size 1
21021 return 1;
21022 }
21023 }
21024 }
21025
21028 size_type max_size() const noexcept
21029 {
21030 switch (m_type)
21031 {
21032 case value_t::array:
21033 {
21034 // delegate call to array_t::max_size()
21035 return m_value.array->max_size();
21036 }
21037
21038 case value_t::object:
21039 {
21040 // delegate call to object_t::max_size()
21041 return m_value.object->max_size();
21042 }
21043
21044 case value_t::null:
21045 case value_t::string:
21046 case value_t::boolean:
21047 case value_t::number_integer:
21048 case value_t::number_unsigned:
21049 case value_t::number_float:
21050 case value_t::binary:
21051 case value_t::discarded:
21052 default:
21053 {
21054 // all other types have max_size() == size()
21055 return size();
21056 }
21057 }
21058 }
21059
21061
21062
21064 // modifiers //
21066
21069
21072 void clear() noexcept
21073 {
21074 switch (m_type)
21075 {
21076 case value_t::number_integer:
21077 {
21078 m_value.number_integer = 0;
21079 break;
21080 }
21081
21082 case value_t::number_unsigned:
21083 {
21084 m_value.number_unsigned = 0;
21085 break;
21086 }
21087
21088 case value_t::number_float:
21089 {
21090 m_value.number_float = 0.0;
21091 break;
21092 }
21093
21094 case value_t::boolean:
21095 {
21096 m_value.boolean = false;
21097 break;
21098 }
21099
21100 case value_t::string:
21101 {
21102 m_value.string->clear();
21103 break;
21104 }
21105
21106 case value_t::binary:
21107 {
21108 m_value.binary->clear();
21109 break;
21110 }
21111
21112 case value_t::array:
21113 {
21114 m_value.array->clear();
21115 break;
21116 }
21117
21118 case value_t::object:
21119 {
21120 m_value.object->clear();
21121 break;
21122 }
21123
21124 case value_t::null:
21125 case value_t::discarded:
21126 default:
21127 break;
21128 }
21129 }
21130
21134 {
21135 // push_back only works for null objects or arrays
21136 if (JSON_HEDLEY_UNLIKELY(!(is_null() || is_array())))
21137 {
21138 JSON_THROW(type_error::create(308, detail::concat("cannot use push_back() with ", type_name()), this));
21139 }
21140
21141 // transform null object into an array
21142 if (is_null())
21143 {
21144 m_type = value_t::array;
21145 m_value = value_t::array;
21146 assert_invariant();
21147 }
21148
21149 // add element to array (move semantics)
21150 const auto old_capacity = m_value.array->capacity();
21151 m_value.array->push_back(std::move(val));
21152 set_parent(m_value.array->back(), old_capacity);
21153 // if val is moved from, basic_json move constructor marks it null, so we do not call the destructor
21154 }
21155
21159 {
21161 return *this;
21162 }
21163
21167 {
21168 // push_back only works for null objects or arrays
21169 if (JSON_HEDLEY_UNLIKELY(!(is_null() || is_array())))
21170 {
21171 JSON_THROW(type_error::create(308, detail::concat("cannot use push_back() with ", type_name()), this));
21172 }
21173
21174 // transform null object into an array
21175 if (is_null())
21176 {
21177 m_type = value_t::array;
21178 m_value = value_t::array;
21179 assert_invariant();
21180 }
21181
21182 // add element to array
21183 const auto old_capacity = m_value.array->capacity();
21184 m_value.array->push_back(val);
21185 set_parent(m_value.array->back(), old_capacity);
21186 }
21187
21191 {
21192 push_back(val);
21193 return *this;
21194 }
21195
21198 void push_back(const typename object_t::value_type& val)
21199 {
21200 // push_back only works for null objects or objects
21201 if (JSON_HEDLEY_UNLIKELY(!(is_null() || is_object())))
21202 {
21203 JSON_THROW(type_error::create(308, detail::concat("cannot use push_back() with ", type_name()), this));
21204 }
21205
21206 // transform null object into an object
21207 if (is_null())
21208 {
21209 m_type = value_t::object;
21210 m_value = value_t::object;
21211 assert_invariant();
21212 }
21213
21214 // add element to object
21215 auto res = m_value.object->insert(val);
21216 set_parent(res.first->second);
21217 }
21218
21221 reference operator+=(const typename object_t::value_type& val)
21222 {
21223 push_back(val);
21224 return *this;
21225 }
21226
21230 {
21231 if (is_object() && init.size() == 2 && (*init.begin())->is_string())
21232 {
21233 basic_json&& key = init.begin()->moved_or_copied();
21234 push_back(typename object_t::value_type(
21235 std::move(key.get_ref<string_t&>()), (init.begin() + 1)->moved_or_copied()));
21236 }
21237 else
21238 {
21239 push_back(basic_json(init));
21240 }
21241 }
21242
21246 {
21247 push_back(init);
21248 return *this;
21249 }
21250
21253 template<class... Args>
21254 reference emplace_back(Args&& ... args)
21255 {
21256 // emplace_back only works for null objects or arrays
21257 if (JSON_HEDLEY_UNLIKELY(!(is_null() || is_array())))
21258 {
21259 JSON_THROW(type_error::create(311, detail::concat("cannot use emplace_back() with ", type_name()), this));
21260 }
21261
21262 // transform null object into an array
21263 if (is_null())
21264 {
21265 m_type = value_t::array;
21266 m_value = value_t::array;
21267 assert_invariant();
21268 }
21269
21270 // add element to array (perfect forwarding)
21271 const auto old_capacity = m_value.array->capacity();
21272 m_value.array->emplace_back(std::forward<Args>(args)...);
21273 return set_parent(m_value.array->back(), old_capacity);
21274 }
21275
21278 template<class... Args>
21279 std::pair<iterator, bool> emplace(Args&& ... args)
21280 {
21281 // emplace only works for null objects or arrays
21282 if (JSON_HEDLEY_UNLIKELY(!(is_null() || is_object())))
21283 {
21284 JSON_THROW(type_error::create(311, detail::concat("cannot use emplace() with ", type_name()), this));
21285 }
21286
21287 // transform null object into an object
21288 if (is_null())
21289 {
21290 m_type = value_t::object;
21291 m_value = value_t::object;
21292 assert_invariant();
21293 }
21294
21295 // add element to array (perfect forwarding)
21296 auto res = m_value.object->emplace(std::forward<Args>(args)...);
21297 set_parent(res.first->second);
21298
21299 // create result iterator and set iterator to the result of emplace
21300 auto it = begin();
21301 it.m_it.object_iterator = res.first;
21302
21303 // return pair of iterator and boolean
21304 return {it, res.second};
21305 }
21306
21310 template<typename... Args>
21312 {
21313 iterator result(this);
21314 JSON_ASSERT(m_value.array != nullptr);
21315
21316 auto insert_pos = std::distance(m_value.array->begin(), pos.m_it.array_iterator);
21317 m_value.array->insert(pos.m_it.array_iterator, std::forward<Args>(args)...);
21318 result.m_it.array_iterator = m_value.array->begin() + insert_pos;
21319
21320 // This could have been written as:
21321 // result.m_it.array_iterator = m_value.array->insert(pos.m_it.array_iterator, cnt, val);
21322 // but the return value of insert is missing in GCC 4.8, so it is written this way instead.
21323
21324 set_parents();
21325 return result;
21326 }
21327
21331 {
21332 // insert only works for arrays
21334 {
21335 // check if iterator pos fits to this JSON value
21336 if (JSON_HEDLEY_UNLIKELY(pos.m_object != this))
21337 {
21338 JSON_THROW(invalid_iterator::create(202, "iterator does not fit current value", this));
21339 }
21340
21341 // insert to array and return iterator
21342 return insert_iterator(pos, val);
21343 }
21344
21345 JSON_THROW(type_error::create(309, detail::concat("cannot use insert() with ", type_name()), this));
21346 }
21347
21351 {
21352 return insert(pos, val);
21353 }
21354
21358 {
21359 // insert only works for arrays
21361 {
21362 // check if iterator pos fits to this JSON value
21363 if (JSON_HEDLEY_UNLIKELY(pos.m_object != this))
21364 {
21365 JSON_THROW(invalid_iterator::create(202, "iterator does not fit current value", this));
21366 }
21367
21368 // insert to array and return iterator
21369 return insert_iterator(pos, cnt, val);
21370 }
21371
21372 JSON_THROW(type_error::create(309, detail::concat("cannot use insert() with ", type_name()), this));
21373 }
21374
21378 {
21379 // insert only works for arrays
21381 {
21382 JSON_THROW(type_error::create(309, detail::concat("cannot use insert() with ", type_name()), this));
21383 }
21384
21385 // check if iterator pos fits to this JSON value
21386 if (JSON_HEDLEY_UNLIKELY(pos.m_object != this))
21387 {
21388 JSON_THROW(invalid_iterator::create(202, "iterator does not fit current value", this));
21389 }
21390
21391 // check if range iterators belong to the same JSON object
21392 if (JSON_HEDLEY_UNLIKELY(first.m_object != last.m_object))
21393 {
21394 JSON_THROW(invalid_iterator::create(210, "iterators do not fit", this));
21395 }
21396
21397 if (JSON_HEDLEY_UNLIKELY(first.m_object == this))
21398 {
21399 JSON_THROW(invalid_iterator::create(211, "passed iterators may not belong to container", this));
21400 }
21401
21402 // insert to array and return iterator
21404 }
21405
21409 {
21410 // insert only works for arrays
21412 {
21413 JSON_THROW(type_error::create(309, detail::concat("cannot use insert() with ", type_name()), this));
21414 }
21415
21416 // check if iterator pos fits to this JSON value
21417 if (JSON_HEDLEY_UNLIKELY(pos.m_object != this))
21418 {
21419 JSON_THROW(invalid_iterator::create(202, "iterator does not fit current value", this));
21420 }
21421
21422 // insert to array and return iterator
21423 return insert_iterator(pos, ilist.begin(), ilist.end());
21424 }
21425
21429 {
21430 // insert only works for objects
21432 {
21433 JSON_THROW(type_error::create(309, detail::concat("cannot use insert() with ", type_name()), this));
21434 }
21435
21436 // check if range iterators belong to the same JSON object
21437 if (JSON_HEDLEY_UNLIKELY(first.m_object != last.m_object))
21438 {
21439 JSON_THROW(invalid_iterator::create(210, "iterators do not fit", this));
21440 }
21441
21442 // passed iterators must belong to objects
21443 if (JSON_HEDLEY_UNLIKELY(!first.m_object->is_object()))
21444 {
21445 JSON_THROW(invalid_iterator::create(202, "iterators first and last must point to objects", this));
21446 }
21447
21448 m_value.object->insert(first.m_it.object_iterator, last.m_it.object_iterator);
21449 }
21450
21453 void update(const_reference j, bool merge_objects = false)
21454 {
21455 update(j.begin(), j.end(), merge_objects);
21456 }
21457
21460 void update(const_iterator first, const_iterator last, bool merge_objects = false)
21461 {
21462 // implicitly convert null value to an empty object
21463 if (is_null())
21464 {
21465 m_type = value_t::object;
21466 m_value.object = create<object_t>();
21467 assert_invariant();
21468 }
21469
21471 {
21472 JSON_THROW(type_error::create(312, detail::concat("cannot use update() with ", type_name()), this));
21473 }
21474
21475 // check if range iterators belong to the same JSON object
21476 if (JSON_HEDLEY_UNLIKELY(first.m_object != last.m_object))
21477 {
21478 JSON_THROW(invalid_iterator::create(210, "iterators do not fit", this));
21479 }
21480
21481 // passed iterators must belong to objects
21482 if (JSON_HEDLEY_UNLIKELY(!first.m_object->is_object()))
21483 {
21484 JSON_THROW(type_error::create(312, detail::concat("cannot use update() with ", first.m_object->type_name()), first.m_object));
21485 }
21486
21487 for (auto it = first; it != last; ++it)
21488 {
21489 if (merge_objects && it.value().is_object())
21490 {
21491 auto it2 = m_value.object->find(it.key());
21492 if (it2 != m_value.object->end())
21493 {
21494 it2->second.update(it.value(), true);
21495 continue;
21496 }
21497 }
21498 m_value.object->operator[](it.key()) = it.value();
21499#if JSON_DIAGNOSTICS
21500 m_value.object->operator[](it.key()).m_parent = this;
21501#endif
21502 }
21503 }
21504
21507 void swap(reference other) noexcept (
21508 std::is_nothrow_move_constructible<value_t>::value&&
21509 std::is_nothrow_move_assignable<value_t>::value&&
21510 std::is_nothrow_move_constructible<json_value>::value&&
21511 std::is_nothrow_move_assignable<json_value>::value
21512 )
21513 {
21514 std::swap(m_type, other.m_type);
21515 std::swap(m_value, other.m_value);
21516
21517 set_parents();
21518 other.set_parents();
21519 assert_invariant();
21520 }
21521
21524 friend void swap(reference left, reference right) noexcept (
21525 std::is_nothrow_move_constructible<value_t>::value&&
21526 std::is_nothrow_move_assignable<value_t>::value&&
21527 std::is_nothrow_move_constructible<json_value>::value&&
21528 std::is_nothrow_move_assignable<json_value>::value
21529 )
21530 {
21531 left.swap(right);
21532 }
21533
21536 void swap(array_t& other) // NOLINT(bugprone-exception-escape)
21537 {
21538 // swap only works for arrays
21540 {
21541 std::swap(*(m_value.array), other);
21542 }
21543 else
21544 {
21545 JSON_THROW(type_error::create(310, detail::concat("cannot use swap() with ", type_name()), this));
21546 }
21547 }
21548
21551 void swap(object_t& other) // NOLINT(bugprone-exception-escape)
21552 {
21553 // swap only works for objects
21555 {
21556 std::swap(*(m_value.object), other);
21557 }
21558 else
21559 {
21560 JSON_THROW(type_error::create(310, detail::concat("cannot use swap() with ", type_name()), this));
21561 }
21562 }
21563
21566 void swap(string_t& other) // NOLINT(bugprone-exception-escape)
21567 {
21568 // swap only works for strings
21570 {
21571 std::swap(*(m_value.string), other);
21572 }
21573 else
21574 {
21575 JSON_THROW(type_error::create(310, detail::concat("cannot use swap() with ", type_name()), this));
21576 }
21577 }
21578
21581 void swap(binary_t& other) // NOLINT(bugprone-exception-escape)
21582 {
21583 // swap only works for strings
21585 {
21586 std::swap(*(m_value.binary), other);
21587 }
21588 else
21589 {
21590 JSON_THROW(type_error::create(310, detail::concat("cannot use swap() with ", type_name()), this));
21591 }
21592 }
21593
21596 void swap(typename binary_t::container_type& other) // NOLINT(bugprone-exception-escape)
21597 {
21598 // swap only works for strings
21600 {
21601 std::swap(*(m_value.binary), other);
21602 }
21603 else
21604 {
21605 JSON_THROW(type_error::create(310, detail::concat("cannot use swap() with ", type_name()), this));
21606 }
21607 }
21608
21610
21611 public:
21613 // lexicographical comparison operators //
21615
21618
21621 friend bool operator==(const_reference lhs, const_reference rhs) noexcept
21622 {
21623#ifdef __GNUC__
21624#pragma GCC diagnostic push
21625#pragma GCC diagnostic ignored "-Wfloat-equal"
21626#endif
21627 const auto lhs_type = lhs.type();
21628 const auto rhs_type = rhs.type();
21629
21630 if (lhs_type == rhs_type)
21631 {
21632 switch (lhs_type)
21633 {
21634 case value_t::array:
21635 return *lhs.m_value.array == *rhs.m_value.array;
21636
21637 case value_t::object:
21638 return *lhs.m_value.object == *rhs.m_value.object;
21639
21640 case value_t::null:
21641 return true;
21642
21643 case value_t::string:
21644 return *lhs.m_value.string == *rhs.m_value.string;
21645
21646 case value_t::boolean:
21647 return lhs.m_value.boolean == rhs.m_value.boolean;
21648
21649 case value_t::number_integer:
21650 return lhs.m_value.number_integer == rhs.m_value.number_integer;
21651
21652 case value_t::number_unsigned:
21653 return lhs.m_value.number_unsigned == rhs.m_value.number_unsigned;
21654
21655 case value_t::number_float:
21656 return lhs.m_value.number_float == rhs.m_value.number_float;
21657
21658 case value_t::binary:
21659 return *lhs.m_value.binary == *rhs.m_value.binary;
21660
21661 case value_t::discarded:
21662 default:
21663 return false;
21664 }
21665 }
21666 else if (lhs_type == value_t::number_integer && rhs_type == value_t::number_float)
21667 {
21668 return static_cast<number_float_t>(lhs.m_value.number_integer) == rhs.m_value.number_float;
21669 }
21670 else if (lhs_type == value_t::number_float && rhs_type == value_t::number_integer)
21671 {
21672 return lhs.m_value.number_float == static_cast<number_float_t>(rhs.m_value.number_integer);
21673 }
21674 else if (lhs_type == value_t::number_unsigned && rhs_type == value_t::number_float)
21675 {
21676 return static_cast<number_float_t>(lhs.m_value.number_unsigned) == rhs.m_value.number_float;
21677 }
21678 else if (lhs_type == value_t::number_float && rhs_type == value_t::number_unsigned)
21679 {
21680 return lhs.m_value.number_float == static_cast<number_float_t>(rhs.m_value.number_unsigned);
21681 }
21682 else if (lhs_type == value_t::number_unsigned && rhs_type == value_t::number_integer)
21683 {
21684 return static_cast<number_integer_t>(lhs.m_value.number_unsigned) == rhs.m_value.number_integer;
21685 }
21686 else if (lhs_type == value_t::number_integer && rhs_type == value_t::number_unsigned)
21687 {
21688 return lhs.m_value.number_integer == static_cast<number_integer_t>(rhs.m_value.number_unsigned);
21689 }
21690
21691 return false;
21692#ifdef __GNUC__
21693#pragma GCC diagnostic pop
21694#endif
21695 }
21696
21699 template<typename ScalarType, typename std::enable_if<
21700 std::is_scalar<ScalarType>::value, int>::type = 0>
21701 friend bool operator==(const_reference lhs, ScalarType rhs) noexcept
21702 {
21703 return lhs == basic_json(rhs);
21704 }
21705
21708 template<typename ScalarType, typename std::enable_if<
21709 std::is_scalar<ScalarType>::value, int>::type = 0>
21710 friend bool operator==(ScalarType lhs, const_reference rhs) noexcept
21711 {
21712 return basic_json(lhs) == rhs;
21713 }
21714
21717 friend bool operator!=(const_reference lhs, const_reference rhs) noexcept
21718 {
21719 return !(lhs == rhs);
21720 }
21721
21724 template<typename ScalarType, typename std::enable_if<
21725 std::is_scalar<ScalarType>::value, int>::type = 0>
21726 friend bool operator!=(const_reference lhs, ScalarType rhs) noexcept
21727 {
21728 return lhs != basic_json(rhs);
21729 }
21730
21733 template<typename ScalarType, typename std::enable_if<
21734 std::is_scalar<ScalarType>::value, int>::type = 0>
21735 friend bool operator!=(ScalarType lhs, const_reference rhs) noexcept
21736 {
21737 return basic_json(lhs) != rhs;
21738 }
21739
21742 friend bool operator<(const_reference lhs, const_reference rhs) noexcept
21743 {
21744 const auto lhs_type = lhs.type();
21745 const auto rhs_type = rhs.type();
21746
21747 if (lhs_type == rhs_type)
21748 {
21749 switch (lhs_type)
21750 {
21751 case value_t::array:
21752 // note parentheses are necessary, see
21753 // https://github.com/nlohmann/json/issues/1530
21754 return (*lhs.m_value.array) < (*rhs.m_value.array);
21755
21756 case value_t::object:
21757 return (*lhs.m_value.object) < (*rhs.m_value.object);
21758
21759 case value_t::null:
21760 return false;
21761
21762 case value_t::string:
21763 return (*lhs.m_value.string) < (*rhs.m_value.string);
21764
21765 case value_t::boolean:
21766 return (lhs.m_value.boolean) < (rhs.m_value.boolean);
21767
21768 case value_t::number_integer:
21769 return (lhs.m_value.number_integer) < (rhs.m_value.number_integer);
21770
21771 case value_t::number_unsigned:
21772 return (lhs.m_value.number_unsigned) < (rhs.m_value.number_unsigned);
21773
21774 case value_t::number_float:
21775 return (lhs.m_value.number_float) < (rhs.m_value.number_float);
21776
21777 case value_t::binary:
21778 return (*lhs.m_value.binary) < (*rhs.m_value.binary);
21779
21780 case value_t::discarded:
21781 default:
21782 return false;
21783 }
21784 }
21785 else if (lhs_type == value_t::number_integer && rhs_type == value_t::number_float)
21786 {
21787 return static_cast<number_float_t>(lhs.m_value.number_integer) < rhs.m_value.number_float;
21788 }
21789 else if (lhs_type == value_t::number_float && rhs_type == value_t::number_integer)
21790 {
21791 return lhs.m_value.number_float < static_cast<number_float_t>(rhs.m_value.number_integer);
21792 }
21793 else if (lhs_type == value_t::number_unsigned && rhs_type == value_t::number_float)
21794 {
21795 return static_cast<number_float_t>(lhs.m_value.number_unsigned) < rhs.m_value.number_float;
21796 }
21797 else if (lhs_type == value_t::number_float && rhs_type == value_t::number_unsigned)
21798 {
21799 return lhs.m_value.number_float < static_cast<number_float_t>(rhs.m_value.number_unsigned);
21800 }
21801 else if (lhs_type == value_t::number_integer && rhs_type == value_t::number_unsigned)
21802 {
21803 return lhs.m_value.number_integer < static_cast<number_integer_t>(rhs.m_value.number_unsigned);
21804 }
21805 else if (lhs_type == value_t::number_unsigned && rhs_type == value_t::number_integer)
21806 {
21807 return static_cast<number_integer_t>(lhs.m_value.number_unsigned) < rhs.m_value.number_integer;
21808 }
21809
21810 // We only reach this line if we cannot compare values. In that case,
21811 // we compare types. Note we have to call the operator explicitly,
21812 // because MSVC has problems otherwise.
21813 return operator<(lhs_type, rhs_type);
21814 }
21815
21818 template<typename ScalarType, typename std::enable_if<
21819 std::is_scalar<ScalarType>::value, int>::type = 0>
21820 friend bool operator<(const_reference lhs, ScalarType rhs) noexcept
21821 {
21822 return lhs < basic_json(rhs);
21823 }
21824
21827 template<typename ScalarType, typename std::enable_if<
21828 std::is_scalar<ScalarType>::value, int>::type = 0>
21829 friend bool operator<(ScalarType lhs, const_reference rhs) noexcept
21830 {
21831 return basic_json(lhs) < rhs;
21832 }
21833
21836 friend bool operator<=(const_reference lhs, const_reference rhs) noexcept
21837 {
21838 return !(rhs < lhs);
21839 }
21840
21843 template<typename ScalarType, typename std::enable_if<
21844 std::is_scalar<ScalarType>::value, int>::type = 0>
21845 friend bool operator<=(const_reference lhs, ScalarType rhs) noexcept
21846 {
21847 return lhs <= basic_json(rhs);
21848 }
21849
21852 template<typename ScalarType, typename std::enable_if<
21853 std::is_scalar<ScalarType>::value, int>::type = 0>
21854 friend bool operator<=(ScalarType lhs, const_reference rhs) noexcept
21855 {
21856 return basic_json(lhs) <= rhs;
21857 }
21858
21861 friend bool operator>(const_reference lhs, const_reference rhs) noexcept
21862 {
21863 return !(lhs <= rhs);
21864 }
21865
21868 template<typename ScalarType, typename std::enable_if<
21869 std::is_scalar<ScalarType>::value, int>::type = 0>
21870 friend bool operator>(const_reference lhs, ScalarType rhs) noexcept
21871 {
21872 return lhs > basic_json(rhs);
21873 }
21874
21877 template<typename ScalarType, typename std::enable_if<
21878 std::is_scalar<ScalarType>::value, int>::type = 0>
21879 friend bool operator>(ScalarType lhs, const_reference rhs) noexcept
21880 {
21881 return basic_json(lhs) > rhs;
21882 }
21883
21886 friend bool operator>=(const_reference lhs, const_reference rhs) noexcept
21887 {
21888 return !(lhs < rhs);
21889 }
21890
21893 template<typename ScalarType, typename std::enable_if<
21894 std::is_scalar<ScalarType>::value, int>::type = 0>
21895 friend bool operator>=(const_reference lhs, ScalarType rhs) noexcept
21896 {
21897 return lhs >= basic_json(rhs);
21898 }
21899
21902 template<typename ScalarType, typename std::enable_if<
21903 std::is_scalar<ScalarType>::value, int>::type = 0>
21904 friend bool operator>=(ScalarType lhs, const_reference rhs) noexcept
21905 {
21906 return basic_json(lhs) >= rhs;
21907 }
21908
21910
21912 // serialization //
21914
21917#ifndef JSON_NO_IO
21920 friend std::ostream& operator<<(std::ostream& o, const basic_json& j)
21921 {
21922 // read width member and use it as indentation parameter if nonzero
21923 const bool pretty_print = o.width() > 0;
21924 const auto indentation = pretty_print ? o.width() : 0;
21925
21926 // reset width to 0 for subsequent calls to this stream
21927 o.width(0);
21928
21929 // do the actual serialization
21930 serializer s(detail::output_adapter<char>(o), o.fill());
21931 s.dump(j, pretty_print, false, static_cast<unsigned int>(indentation));
21932 return o;
21933 }
21934
21941 JSON_HEDLEY_DEPRECATED_FOR(3.0.0, operator<<(std::ostream&, const basic_json&))
21942 friend std::ostream& operator>>(const basic_json& j, std::ostream& o)
21943 {
21944 return o << j;
21945 }
21946#endif // JSON_NO_IO
21948
21949
21951 // deserialization //
21953
21956
21959 template<typename InputType>
21961 static basic_json parse(InputType&& i,
21962 const parser_callback_t cb = nullptr,
21963 const bool allow_exceptions = true,
21964 const bool ignore_comments = false)
21965 {
21967 parser(detail::input_adapter(std::forward<InputType>(i)), cb, allow_exceptions, ignore_comments).parse(true, result);
21968 return result;
21969 }
21970
21973 template<typename IteratorType>
21975 static basic_json parse(IteratorType first,
21976 IteratorType last,
21977 const parser_callback_t cb = nullptr,
21978 const bool allow_exceptions = true,
21979 const bool ignore_comments = false)
21980 {
21982 parser(detail::input_adapter(std::move(first), std::move(last)), cb, allow_exceptions, ignore_comments).parse(true, result);
21983 return result;
21984 }
21985
21987 JSON_HEDLEY_DEPRECATED_FOR(3.8.0, parse(ptr, ptr + len))
21988 static basic_json parse(detail::span_input_adapter&& i,
21989 const parser_callback_t cb = nullptr,
21990 const bool allow_exceptions = true,
21991 const bool ignore_comments = false)
21992 {
21994 parser(i.get(), cb, allow_exceptions, ignore_comments).parse(true, result);
21995 return result;
21996 }
21997
22000 template<typename InputType>
22001 static bool accept(InputType&& i,
22002 const bool ignore_comments = false)
22003 {
22004 return parser(detail::input_adapter(std::forward<InputType>(i)), nullptr, false, ignore_comments).accept(true);
22005 }
22006
22009 template<typename IteratorType>
22010 static bool accept(IteratorType first, IteratorType last,
22011 const bool ignore_comments = false)
22012 {
22013 return parser(detail::input_adapter(std::move(first), std::move(last)), nullptr, false, ignore_comments).accept(true);
22014 }
22015
22017 JSON_HEDLEY_DEPRECATED_FOR(3.8.0, accept(ptr, ptr + len))
22018 static bool accept(detail::span_input_adapter&& i,
22019 const bool ignore_comments = false)
22020 {
22021 return parser(i.get(), nullptr, false, ignore_comments).accept(true);
22022 }
22023
22026 template <typename InputType, typename SAX>
22028 static bool sax_parse(InputType&& i, SAX* sax,
22029 input_format_t format = input_format_t::json,
22030 const bool strict = true,
22031 const bool ignore_comments = false)
22032 {
22033 auto ia = detail::input_adapter(std::forward<InputType>(i));
22034 return format == input_format_t::json
22035 ? parser(std::move(ia), nullptr, true, ignore_comments).sax_parse(sax, strict)
22037 }
22038
22041 template<class IteratorType, class SAX>
22043 static bool sax_parse(IteratorType first, IteratorType last, SAX* sax,
22044 input_format_t format = input_format_t::json,
22045 const bool strict = true,
22046 const bool ignore_comments = false)
22047 {
22048 auto ia = detail::input_adapter(std::move(first), std::move(last));
22049 return format == input_format_t::json
22050 ? parser(std::move(ia), nullptr, true, ignore_comments).sax_parse(sax, strict)
22052 }
22053
22059 template <typename SAX>
22060 JSON_HEDLEY_DEPRECATED_FOR(3.8.0, sax_parse(ptr, ptr + len, ...))
22062 static bool sax_parse(detail::span_input_adapter&& i, SAX* sax,
22063 input_format_t format = input_format_t::json,
22064 const bool strict = true,
22065 const bool ignore_comments = false)
22066 {
22067 auto ia = i.get();
22068 return format == input_format_t::json
22069 // NOLINTNEXTLINE(hicpp-move-const-arg,performance-move-const-arg)
22070 ? parser(std::move(ia), nullptr, true, ignore_comments).sax_parse(sax, strict)
22071 // NOLINTNEXTLINE(hicpp-move-const-arg,performance-move-const-arg)
22073 }
22074#ifndef JSON_NO_IO
22081 JSON_HEDLEY_DEPRECATED_FOR(3.0.0, operator>>(std::istream&, basic_json&))
22082 friend std::istream& operator<<(basic_json& j, std::istream& i)
22083 {
22084 return operator>>(i, j);
22085 }
22086
22089 friend std::istream& operator>>(std::istream& i, basic_json& j)
22090 {
22091 parser(detail::input_adapter(i)).parse(false, j);
22092 return i;
22093 }
22094#endif // JSON_NO_IO
22096
22098 // convenience functions //
22100
22104 const char* type_name() const noexcept
22105 {
22106 switch (m_type)
22107 {
22108 case value_t::null:
22109 return "null";
22110 case value_t::object:
22111 return "object";
22112 case value_t::array:
22113 return "array";
22114 case value_t::string:
22115 return "string";
22116 case value_t::boolean:
22117 return "boolean";
22118 case value_t::binary:
22119 return "binary";
22120 case value_t::discarded:
22121 return "discarded";
22122 case value_t::number_integer:
22123 case value_t::number_unsigned:
22124 case value_t::number_float:
22125 default:
22126 return "number";
22127 }
22128 }
22129
22130
22133 // member variables //
22135
22137 value_t m_type = value_t::null;
22138
22140 json_value m_value = {};
22141
22142#if JSON_DIAGNOSTICS
22144 basic_json* m_parent = nullptr;
22145#endif
22146
22148 // binary serialization/deserialization //
22150
22153
22154 public:
22157 static std::vector<std::uint8_t> to_cbor(const basic_json& j)
22158 {
22159 std::vector<std::uint8_t> result;
22160 to_cbor(j, result);
22161 return result;
22162 }
22163
22166 static void to_cbor(const basic_json& j, detail::output_adapter<std::uint8_t> o)
22167 {
22168 binary_writer<std::uint8_t>(o).write_cbor(j);
22169 }
22170
22173 static void to_cbor(const basic_json& j, detail::output_adapter<char> o)
22174 {
22175 binary_writer<char>(o).write_cbor(j);
22176 }
22177
22180 static std::vector<std::uint8_t> to_msgpack(const basic_json& j)
22181 {
22182 std::vector<std::uint8_t> result;
22183 to_msgpack(j, result);
22184 return result;
22185 }
22186
22189 static void to_msgpack(const basic_json& j, detail::output_adapter<std::uint8_t> o)
22190 {
22191 binary_writer<std::uint8_t>(o).write_msgpack(j);
22192 }
22193
22196 static void to_msgpack(const basic_json& j, detail::output_adapter<char> o)
22197 {
22198 binary_writer<char>(o).write_msgpack(j);
22199 }
22200
22203 static std::vector<std::uint8_t> to_ubjson(const basic_json& j,
22204 const bool use_size = false,
22205 const bool use_type = false)
22206 {
22207 std::vector<std::uint8_t> result;
22208 to_ubjson(j, result, use_size, use_type);
22209 return result;
22210 }
22211
22214 static void to_ubjson(const basic_json& j, detail::output_adapter<std::uint8_t> o,
22215 const bool use_size = false, const bool use_type = false)
22216 {
22217 binary_writer<std::uint8_t>(o).write_ubjson(j, use_size, use_type);
22218 }
22219
22222 static void to_ubjson(const basic_json& j, detail::output_adapter<char> o,
22223 const bool use_size = false, const bool use_type = false)
22224 {
22225 binary_writer<char>(o).write_ubjson(j, use_size, use_type);
22226 }
22227
22230 static std::vector<std::uint8_t> to_bjdata(const basic_json& j,
22231 const bool use_size = false,
22232 const bool use_type = false)
22233 {
22234 std::vector<std::uint8_t> result;
22235 to_bjdata(j, result, use_size, use_type);
22236 return result;
22237 }
22238
22241 static void to_bjdata(const basic_json& j, detail::output_adapter<std::uint8_t> o,
22242 const bool use_size = false, const bool use_type = false)
22243 {
22244 binary_writer<std::uint8_t>(o).write_ubjson(j, use_size, use_type, true, true);
22245 }
22246
22249 static void to_bjdata(const basic_json& j, detail::output_adapter<char> o,
22250 const bool use_size = false, const bool use_type = false)
22251 {
22252 binary_writer<char>(o).write_ubjson(j, use_size, use_type, true, true);
22253 }
22254
22257 static std::vector<std::uint8_t> to_bson(const basic_json& j)
22258 {
22259 std::vector<std::uint8_t> result;
22260 to_bson(j, result);
22261 return result;
22262 }
22263
22266 static void to_bson(const basic_json& j, detail::output_adapter<std::uint8_t> o)
22267 {
22268 binary_writer<std::uint8_t>(o).write_bson(j);
22269 }
22270
22273 static void to_bson(const basic_json& j, detail::output_adapter<char> o)
22274 {
22275 binary_writer<char>(o).write_bson(j);
22276 }
22277
22280 template<typename InputType>
22282 static basic_json from_cbor(InputType&& i,
22283 const bool strict = true,
22284 const bool allow_exceptions = true,
22285 const cbor_tag_handler_t tag_handler = cbor_tag_handler_t::error)
22286 {
22288 detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
22289 auto ia = detail::input_adapter(std::forward<InputType>(i));
22290 const bool res = binary_reader<decltype(ia)>(std::move(ia), input_format_t::cbor).sax_parse(input_format_t::cbor, &sdp, strict, tag_handler);
22291 return res ? result : basic_json(value_t::discarded);
22292 }
22293
22296 template<typename IteratorType>
22298 static basic_json from_cbor(IteratorType first, IteratorType last,
22299 const bool strict = true,
22300 const bool allow_exceptions = true,
22301 const cbor_tag_handler_t tag_handler = cbor_tag_handler_t::error)
22302 {
22304 detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
22305 auto ia = detail::input_adapter(std::move(first), std::move(last));
22306 const bool res = binary_reader<decltype(ia)>(std::move(ia), input_format_t::cbor).sax_parse(input_format_t::cbor, &sdp, strict, tag_handler);
22307 return res ? result : basic_json(value_t::discarded);
22308 }
22309
22310 template<typename T>
22312 JSON_HEDLEY_DEPRECATED_FOR(3.8.0, from_cbor(ptr, ptr + len))
22313 static basic_json from_cbor(const T* ptr, std::size_t len,
22314 const bool strict = true,
22315 const bool allow_exceptions = true,
22316 const cbor_tag_handler_t tag_handler = cbor_tag_handler_t::error)
22317 {
22318 return from_cbor(ptr, ptr + len, strict, allow_exceptions, tag_handler);
22319 }
22320
22321
22323 JSON_HEDLEY_DEPRECATED_FOR(3.8.0, from_cbor(ptr, ptr + len))
22324 static basic_json from_cbor(detail::span_input_adapter&& i,
22325 const bool strict = true,
22326 const bool allow_exceptions = true,
22327 const cbor_tag_handler_t tag_handler = cbor_tag_handler_t::error)
22328 {
22330 detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
22331 auto ia = i.get();
22332 // NOLINTNEXTLINE(hicpp-move-const-arg,performance-move-const-arg)
22333 const bool res = binary_reader<decltype(ia)>(std::move(ia), input_format_t::cbor).sax_parse(input_format_t::cbor, &sdp, strict, tag_handler);
22334 return res ? result : basic_json(value_t::discarded);
22335 }
22336
22339 template<typename InputType>
22341 static basic_json from_msgpack(InputType&& i,
22342 const bool strict = true,
22343 const bool allow_exceptions = true)
22344 {
22346 detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
22347 auto ia = detail::input_adapter(std::forward<InputType>(i));
22348 const bool res = binary_reader<decltype(ia)>(std::move(ia), input_format_t::msgpack).sax_parse(input_format_t::msgpack, &sdp, strict);
22349 return res ? result : basic_json(value_t::discarded);
22350 }
22351
22354 template<typename IteratorType>
22356 static basic_json from_msgpack(IteratorType first, IteratorType last,
22357 const bool strict = true,
22358 const bool allow_exceptions = true)
22359 {
22361 detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
22362 auto ia = detail::input_adapter(std::move(first), std::move(last));
22363 const bool res = binary_reader<decltype(ia)>(std::move(ia), input_format_t::msgpack).sax_parse(input_format_t::msgpack, &sdp, strict);
22364 return res ? result : basic_json(value_t::discarded);
22365 }
22366
22367 template<typename T>
22369 JSON_HEDLEY_DEPRECATED_FOR(3.8.0, from_msgpack(ptr, ptr + len))
22370 static basic_json from_msgpack(const T* ptr, std::size_t len,
22371 const bool strict = true,
22372 const bool allow_exceptions = true)
22373 {
22374 return from_msgpack(ptr, ptr + len, strict, allow_exceptions);
22375 }
22376
22378 JSON_HEDLEY_DEPRECATED_FOR(3.8.0, from_msgpack(ptr, ptr + len))
22379 static basic_json from_msgpack(detail::span_input_adapter&& i,
22380 const bool strict = true,
22381 const bool allow_exceptions = true)
22382 {
22384 detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
22385 auto ia = i.get();
22386 // NOLINTNEXTLINE(hicpp-move-const-arg,performance-move-const-arg)
22387 const bool res = binary_reader<decltype(ia)>(std::move(ia), input_format_t::msgpack).sax_parse(input_format_t::msgpack, &sdp, strict);
22388 return res ? result : basic_json(value_t::discarded);
22389 }
22390
22393 template<typename InputType>
22395 static basic_json from_ubjson(InputType&& i,
22396 const bool strict = true,
22397 const bool allow_exceptions = true)
22398 {
22400 detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
22401 auto ia = detail::input_adapter(std::forward<InputType>(i));
22402 const bool res = binary_reader<decltype(ia)>(std::move(ia), input_format_t::ubjson).sax_parse(input_format_t::ubjson, &sdp, strict);
22403 return res ? result : basic_json(value_t::discarded);
22404 }
22405
22408 template<typename IteratorType>
22410 static basic_json from_ubjson(IteratorType first, IteratorType last,
22411 const bool strict = true,
22412 const bool allow_exceptions = true)
22413 {
22415 detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
22416 auto ia = detail::input_adapter(std::move(first), std::move(last));
22417 const bool res = binary_reader<decltype(ia)>(std::move(ia), input_format_t::ubjson).sax_parse(input_format_t::ubjson, &sdp, strict);
22418 return res ? result : basic_json(value_t::discarded);
22419 }
22420
22421 template<typename T>
22423 JSON_HEDLEY_DEPRECATED_FOR(3.8.0, from_ubjson(ptr, ptr + len))
22424 static basic_json from_ubjson(const T* ptr, std::size_t len,
22425 const bool strict = true,
22426 const bool allow_exceptions = true)
22427 {
22428 return from_ubjson(ptr, ptr + len, strict, allow_exceptions);
22429 }
22430
22432 JSON_HEDLEY_DEPRECATED_FOR(3.8.0, from_ubjson(ptr, ptr + len))
22433 static basic_json from_ubjson(detail::span_input_adapter&& i,
22434 const bool strict = true,
22435 const bool allow_exceptions = true)
22436 {
22438 detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
22439 auto ia = i.get();
22440 // NOLINTNEXTLINE(hicpp-move-const-arg,performance-move-const-arg)
22441 const bool res = binary_reader<decltype(ia)>(std::move(ia), input_format_t::ubjson).sax_parse(input_format_t::ubjson, &sdp, strict);
22442 return res ? result : basic_json(value_t::discarded);
22443 }
22444
22445
22448 template<typename InputType>
22450 static basic_json from_bjdata(InputType&& i,
22451 const bool strict = true,
22452 const bool allow_exceptions = true)
22453 {
22455 detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
22456 auto ia = detail::input_adapter(std::forward<InputType>(i));
22457 const bool res = binary_reader<decltype(ia)>(std::move(ia), input_format_t::bjdata).sax_parse(input_format_t::bjdata, &sdp, strict);
22458 return res ? result : basic_json(value_t::discarded);
22459 }
22460
22463 template<typename IteratorType>
22465 static basic_json from_bjdata(IteratorType first, IteratorType last,
22466 const bool strict = true,
22467 const bool allow_exceptions = true)
22468 {
22470 detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
22471 auto ia = detail::input_adapter(std::move(first), std::move(last));
22472 const bool res = binary_reader<decltype(ia)>(std::move(ia), input_format_t::bjdata).sax_parse(input_format_t::bjdata, &sdp, strict);
22473 return res ? result : basic_json(value_t::discarded);
22474 }
22475
22476 template<typename T>
22478 static basic_json from_bjdata(const T* ptr, std::size_t len,
22479 const bool strict = true,
22480 const bool allow_exceptions = true)
22481 {
22482 return from_bjdata(ptr, ptr + len, strict, allow_exceptions);
22483 }
22484
22486 static basic_json from_bjdata(detail::span_input_adapter&& i,
22487 const bool strict = true,
22488 const bool allow_exceptions = true)
22489 {
22491 detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
22492 auto ia = i.get();
22493 // NOLINTNEXTLINE(hicpp-move-const-arg,performance-move-const-arg)
22494 const bool res = binary_reader<decltype(ia)>(std::move(ia), input_format_t::bjdata).sax_parse(input_format_t::bjdata, &sdp, strict);
22495 return res ? result : basic_json(value_t::discarded);
22496 }
22497
22498
22501 template<typename InputType>
22503 static basic_json from_bson(InputType&& i,
22504 const bool strict = true,
22505 const bool allow_exceptions = true)
22506 {
22508 detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
22509 auto ia = detail::input_adapter(std::forward<InputType>(i));
22510 const bool res = binary_reader<decltype(ia)>(std::move(ia), input_format_t::bson).sax_parse(input_format_t::bson, &sdp, strict);
22511 return res ? result : basic_json(value_t::discarded);
22512 }
22513
22516 template<typename IteratorType>
22518 static basic_json from_bson(IteratorType first, IteratorType last,
22519 const bool strict = true,
22520 const bool allow_exceptions = true)
22521 {
22523 detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
22524 auto ia = detail::input_adapter(std::move(first), std::move(last));
22525 const bool res = binary_reader<decltype(ia)>(std::move(ia), input_format_t::bson).sax_parse(input_format_t::bson, &sdp, strict);
22526 return res ? result : basic_json(value_t::discarded);
22527 }
22528
22529 template<typename T>
22531 JSON_HEDLEY_DEPRECATED_FOR(3.8.0, from_bson(ptr, ptr + len))
22532 static basic_json from_bson(const T* ptr, std::size_t len,
22533 const bool strict = true,
22534 const bool allow_exceptions = true)
22535 {
22536 return from_bson(ptr, ptr + len, strict, allow_exceptions);
22537 }
22538
22540 JSON_HEDLEY_DEPRECATED_FOR(3.8.0, from_bson(ptr, ptr + len))
22541 static basic_json from_bson(detail::span_input_adapter&& i,
22542 const bool strict = true,
22543 const bool allow_exceptions = true)
22544 {
22546 detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
22547 auto ia = i.get();
22548 // NOLINTNEXTLINE(hicpp-move-const-arg,performance-move-const-arg)
22549 const bool res = binary_reader<decltype(ia)>(std::move(ia), input_format_t::bson).sax_parse(input_format_t::bson, &sdp, strict);
22550 return res ? result : basic_json(value_t::discarded);
22551 }
22553
22555 // JSON Pointer support //
22557
22560
22564 {
22565 return ptr.get_unchecked(this);
22566 }
22567
22568 template<typename BasicJsonType, detail::enable_if_t<detail::is_basic_json<BasicJsonType>::value, int> = 0>
22570 reference operator[](const ::nlohmann::json_pointer<BasicJsonType>& ptr)
22571 {
22572 return ptr.get_unchecked(this);
22573 }
22574
22578 {
22579 return ptr.get_unchecked(this);
22580 }
22581
22582 template<typename BasicJsonType, detail::enable_if_t<detail::is_basic_json<BasicJsonType>::value, int> = 0>
22584 const_reference operator[](const ::nlohmann::json_pointer<BasicJsonType>& ptr) const
22585 {
22586 return ptr.get_unchecked(this);
22587 }
22588
22592 {
22593 return ptr.get_checked(this);
22594 }
22595
22596 template<typename BasicJsonType>
22598 reference at(const ::nlohmann::json_pointer<BasicJsonType>& ptr)
22599 {
22600 return ptr.get_checked(this);
22601 }
22602
22606 {
22607 return ptr.get_checked(this);
22608 }
22609
22610 template<typename BasicJsonType>
22612 const_reference at(const ::nlohmann::json_pointer<BasicJsonType>& ptr) const
22613 {
22614 return ptr.get_checked(this);
22615 }
22616
22620 {
22621 basic_json result(value_t::object);
22622 json_pointer::flatten("", *this, result);
22623 return result;
22624 }
22625
22629 {
22630 return json_pointer::unflatten(*this);
22631 }
22632
22634
22636 // JSON Patch functions //
22638
22641
22644 basic_json patch(const basic_json& json_patch) const
22645 {
22646 // make a working copy to apply the patch to
22647 basic_json result = *this;
22648
22649 // the valid JSON Patch operations
22650 enum class patch_operations {add, remove, replace, move, copy, test, invalid};
22651
22652 const auto get_op = [](const std::string & op)
22653 {
22654 if (op == "add")
22655 {
22656 return patch_operations::add;
22657 }
22658 if (op == "remove")
22659 {
22660 return patch_operations::remove;
22661 }
22662 if (op == "replace")
22663 {
22664 return patch_operations::replace;
22665 }
22666 if (op == "move")
22667 {
22668 return patch_operations::move;
22669 }
22670 if (op == "copy")
22671 {
22672 return patch_operations::copy;
22673 }
22674 if (op == "test")
22675 {
22676 return patch_operations::test;
22677 }
22678
22679 return patch_operations::invalid;
22680 };
22681
22682 // wrapper for "add" operation; add value at ptr
22683 const auto operation_add = [&result](json_pointer & ptr, basic_json val)
22684 {
22685 // adding to the root of the target document means replacing it
22686 if (ptr.empty())
22687 {
22688 result = val;
22689 return;
22690 }
22691
22692 // make sure the top element of the pointer exists
22693 json_pointer top_pointer = ptr.top();
22694 if (top_pointer != ptr)
22695 {
22696 result.at(top_pointer);
22697 }
22698
22699 // get reference to parent of JSON pointer ptr
22700 const auto last_path = ptr.back();
22701 ptr.pop_back();
22702 basic_json& parent = result[ptr];
22703
22704 switch (parent.m_type)
22705 {
22706 case value_t::null:
22707 case value_t::object:
22708 {
22709 // use operator[] to add value
22710 parent[last_path] = val;
22711 break;
22712 }
22713
22714 case value_t::array:
22715 {
22716 if (last_path == "-")
22717 {
22718 // special case: append to back
22719 parent.push_back(val);
22720 }
22721 else
22722 {
22723 const auto idx = json_pointer::template array_index<basic_json_t>(last_path);
22724 if (JSON_HEDLEY_UNLIKELY(idx > parent.size()))
22725 {
22726 // avoid undefined behavior
22727 JSON_THROW(out_of_range::create(401, detail::concat("array index ", std::to_string(idx), " is out of range"), &parent));
22728 }
22729
22730 // default case: insert add offset
22731 parent.insert(parent.begin() + static_cast<difference_type>(idx), val);
22732 }
22733 break;
22734 }
22735
22736 // if there exists a parent it cannot be primitive
22737 case value_t::string: // LCOV_EXCL_LINE
22738 case value_t::boolean: // LCOV_EXCL_LINE
22739 case value_t::number_integer: // LCOV_EXCL_LINE
22740 case value_t::number_unsigned: // LCOV_EXCL_LINE
22741 case value_t::number_float: // LCOV_EXCL_LINE
22742 case value_t::binary: // LCOV_EXCL_LINE
22743 case value_t::discarded: // LCOV_EXCL_LINE
22744 default: // LCOV_EXCL_LINE
22745 JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert) LCOV_EXCL_LINE
22746 }
22747 };
22748
22749 // wrapper for "remove" operation; remove value at ptr
22750 const auto operation_remove = [this, &result](json_pointer & ptr)
22751 {
22752 // get reference to parent of JSON pointer ptr
22753 const auto last_path = ptr.back();
22754 ptr.pop_back();
22755 basic_json& parent = result.at(ptr);
22756
22757 // remove child
22758 if (parent.is_object())
22759 {
22760 // perform range check
22761 auto it = parent.find(last_path);
22762 if (JSON_HEDLEY_LIKELY(it != parent.end()))
22763 {
22764 parent.erase(it);
22765 }
22766 else
22767 {
22768 JSON_THROW(out_of_range::create(403, detail::concat("key '", last_path, "' not found"), this));
22769 }
22770 }
22771 else if (parent.is_array())
22772 {
22773 // note erase performs range check
22774 parent.erase(json_pointer::template array_index<basic_json_t>(last_path));
22775 }
22776 };
22777
22778 // type check: top level value must be an array
22779 if (JSON_HEDLEY_UNLIKELY(!json_patch.is_array()))
22780 {
22781 JSON_THROW(parse_error::create(104, 0, "JSON patch must be an array of objects", &json_patch));
22782 }
22783
22784 // iterate and apply the operations
22785 for (const auto& val : json_patch)
22786 {
22787 // wrapper to get a value for an operation
22788 const auto get_value = [&val](const std::string & op,
22789 const std::string & member,
22790 bool string_type) -> basic_json &
22791 {
22792 // find value
22793 auto it = val.m_value.object->find(member);
22794
22795 // context-sensitive error message
22796 const auto error_msg = (op == "op") ? "operation" : detail::concat("operation '", op, '\'');
22797
22798 // check if desired value is present
22799 if (JSON_HEDLEY_UNLIKELY(it == val.m_value.object->end()))
22800 {
22801 // NOLINTNEXTLINE(performance-inefficient-string-concatenation)
22802 JSON_THROW(parse_error::create(105, 0, detail::concat(error_msg, " must have member '", member, "'"), &val));
22803 }
22804
22805 // check if result is of type string
22806 if (JSON_HEDLEY_UNLIKELY(string_type && !it->second.is_string()))
22807 {
22808 // NOLINTNEXTLINE(performance-inefficient-string-concatenation)
22809 JSON_THROW(parse_error::create(105, 0, detail::concat(error_msg, " must have string member '", member, "'"), &val));
22810 }
22811
22812 // no error: return value
22813 return it->second;
22814 };
22815
22816 // type check: every element of the array must be an object
22817 if (JSON_HEDLEY_UNLIKELY(!val.is_object()))
22818 {
22819 JSON_THROW(parse_error::create(104, 0, "JSON patch must be an array of objects", &val));
22820 }
22821
22822 // collect mandatory members
22823 const auto op = get_value("op", "op", true).template get<std::string>();
22824 const auto path = get_value(op, "path", true).template get<std::string>();
22825 json_pointer ptr(path);
22826
22827 switch (get_op(op))
22828 {
22829 case patch_operations::add:
22830 {
22831 operation_add(ptr, get_value("add", "value", false));
22832 break;
22833 }
22834
22835 case patch_operations::remove:
22836 {
22837 operation_remove(ptr);
22838 break;
22839 }
22840
22841 case patch_operations::replace:
22842 {
22843 // the "path" location must exist - use at()
22844 result.at(ptr) = get_value("replace", "value", false);
22845 break;
22846 }
22847
22848 case patch_operations::move:
22849 {
22850 const auto from_path = get_value("move", "from", true).template get<std::string>();
22851 json_pointer from_ptr(from_path);
22852
22853 // the "from" location must exist - use at()
22854 basic_json v = result.at(from_ptr);
22855
22856 // The move operation is functionally identical to a
22857 // "remove" operation on the "from" location, followed
22858 // immediately by an "add" operation at the target
22859 // location with the value that was just removed.
22860 operation_remove(from_ptr);
22861 operation_add(ptr, v);
22862 break;
22863 }
22864
22865 case patch_operations::copy:
22866 {
22867 const auto from_path = get_value("copy", "from", true).template get<std::string>();
22868 const json_pointer from_ptr(from_path);
22869
22870 // the "from" location must exist - use at()
22871 basic_json v = result.at(from_ptr);
22872
22873 // The copy is functionally identical to an "add"
22874 // operation at the target location using the value
22875 // specified in the "from" member.
22876 operation_add(ptr, v);
22877 break;
22878 }
22879
22880 case patch_operations::test:
22881 {
22882 bool success = false;
22883 JSON_TRY
22884 {
22885 // check if "value" matches the one at "path"
22886 // the "path" location must exist - use at()
22887 success = (result.at(ptr) == get_value("test", "value", false));
22888 }
22890 {
22891 // ignore out of range errors: success remains false
22892 }
22893
22894 // throw an exception if test fails
22895 if (JSON_HEDLEY_UNLIKELY(!success))
22896 {
22897 JSON_THROW(other_error::create(501, detail::concat("unsuccessful: ", val.dump()), &val));
22898 }
22899
22900 break;
22901 }
22902
22903 case patch_operations::invalid:
22904 default:
22905 {
22906 // op must be "add", "remove", "replace", "move", "copy", or
22907 // "test"
22908 JSON_THROW(parse_error::create(105, 0, detail::concat("operation value '", op, "' is invalid"), &val));
22909 }
22910 }
22911 }
22912
22913 return result;
22914 }
22915
22920 const std::string& path = "")
22921 {
22922 // the patch
22923 basic_json result(value_t::array);
22924
22925 // if the values are the same, return empty patch
22926 if (source == target)
22927 {
22928 return result;
22929 }
22930
22931 if (source.type() != target.type())
22932 {
22933 // different types: replace value
22934 result.push_back(
22935 {
22936 {"op", "replace"}, {"path", path}, {"value", target}
22937 });
22938 return result;
22939 }
22940
22941 switch (source.type())
22942 {
22943 case value_t::array:
22944 {
22945 // first pass: traverse common elements
22946 std::size_t i = 0;
22947 while (i < source.size() && i < target.size())
22948 {
22949 // recursive call to compare array values at index i
22950 auto temp_diff = diff(source[i], target[i], detail::concat(path, '/', std::to_string(i)));
22951 result.insert(result.end(), temp_diff.begin(), temp_diff.end());
22952 ++i;
22953 }
22954
22955 // We now reached the end of at least one array
22956 // in a second pass, traverse the remaining elements
22957
22958 // remove my remaining elements
22959 const auto end_index = static_cast<difference_type>(result.size());
22960 while (i < source.size())
22961 {
22962 // add operations in reverse order to avoid invalid
22963 // indices
22964 result.insert(result.begin() + end_index, object(
22965 {
22966 {"op", "remove"},
22967 {"path", detail::concat(path, '/', std::to_string(i))}
22968 }));
22969 ++i;
22970 }
22971
22972 // add other remaining elements
22973 while (i < target.size())
22974 {
22975 result.push_back(
22976 {
22977 {"op", "add"},
22978 {"path", detail::concat(path, "/-")},
22979 {"value", target[i]}
22980 });
22981 ++i;
22982 }
22983
22984 break;
22985 }
22986
22987 case value_t::object:
22988 {
22989 // first pass: traverse this object's elements
22990 for (auto it = source.cbegin(); it != source.cend(); ++it)
22991 {
22992 // escape the key name to be used in a JSON patch
22993 const auto path_key = detail::concat(path, '/', detail::escape(it.key()));
22994
22995 if (target.find(it.key()) != target.end())
22996 {
22997 // recursive call to compare object values at key it
22998 auto temp_diff = diff(it.value(), target[it.key()], path_key);
22999 result.insert(result.end(), temp_diff.begin(), temp_diff.end());
23000 }
23001 else
23002 {
23003 // found a key that is not in o -> remove it
23004 result.push_back(object(
23005 {
23006 {"op", "remove"}, {"path", path_key}
23007 }));
23008 }
23009 }
23010
23011 // second pass: traverse other object's elements
23012 for (auto it = target.cbegin(); it != target.cend(); ++it)
23013 {
23014 if (source.find(it.key()) == source.end())
23015 {
23016 // found a key that is not in this -> add it
23017 const auto path_key = detail::concat(path, '/', detail::escape(it.key()));
23018 result.push_back(
23019 {
23020 {"op", "add"}, {"path", path_key},
23021 {"value", it.value()}
23022 });
23023 }
23024 }
23025
23026 break;
23027 }
23028
23029 case value_t::null:
23030 case value_t::string:
23031 case value_t::boolean:
23032 case value_t::number_integer:
23033 case value_t::number_unsigned:
23034 case value_t::number_float:
23035 case value_t::binary:
23036 case value_t::discarded:
23037 default:
23038 {
23039 // both primitive type: replace value
23040 result.push_back(
23041 {
23042 {"op", "replace"}, {"path", path}, {"value", target}
23043 });
23044 break;
23045 }
23046 }
23047
23048 return result;
23049 }
23050
23052
23054 // JSON Merge Patch functions //
23056
23059
23062 void merge_patch(const basic_json& apply_patch)
23063 {
23064 if (apply_patch.is_object())
23065 {
23066 if (!is_object())
23067 {
23068 *this = object();
23069 }
23070 for (auto it = apply_patch.begin(); it != apply_patch.end(); ++it)
23071 {
23072 if (it.value().is_null())
23073 {
23074 erase(it.key());
23075 }
23076 else
23077 {
23078 operator[](it.key()).merge_patch(it.value());
23079 }
23080 }
23081 }
23082 else
23083 {
23084 *this = apply_patch;
23085 }
23086 }
23087
23089};
23090
23094std::string to_string(const NLOHMANN_BASIC_JSON_TPL& j)
23095{
23096 return j.dump();
23097}
23098
23099} // namespace nlohmann
23100
23102// nonmember support //
23104
23105namespace std // NOLINT(cert-dcl58-cpp)
23106{
23107
23112{
23113 std::size_t operator()(const nlohmann::NLOHMANN_BASIC_JSON_TPL& j) const
23114 {
23115 return nlohmann::detail::hash(j);
23116 }
23117};
23118
23119// specialization for std::less<value_t>
23120template<>
23121struct less< ::nlohmann::detail::value_t> // do not remove the space after '<', see https://github.com/nlohmann/json/pull/679
23122{
23128 nlohmann::detail::value_t rhs) const noexcept
23129 {
23130 return nlohmann::detail::operator<(lhs, rhs);
23131 }
23132};
23133
23134// C++20 prohibit function specialization in the std namespace.
23135#ifndef JSON_HAS_CPP_20
23136
23140inline void swap(nlohmann::NLOHMANN_BASIC_JSON_TPL& j1, nlohmann::NLOHMANN_BASIC_JSON_TPL& j2) noexcept( // NOLINT(readability-inconsistent-declaration-parameter-name)
23141 is_nothrow_move_constructible<nlohmann::NLOHMANN_BASIC_JSON_TPL>::value&& // NOLINT(misc-redundant-expression)
23142 is_nothrow_move_assignable<nlohmann::NLOHMANN_BASIC_JSON_TPL>::value)
23143{
23144 j1.swap(j2);
23145}
23146
23147#endif
23148
23149} // namespace std
23150
23154inline nlohmann::json operator "" _json(const char* s, std::size_t n)
23155{
23156 return nlohmann::json::parse(s, s + n);
23157}
23158
23162inline nlohmann::json::json_pointer operator "" _json_pointer(const char* s, std::size_t n)
23163{
23164 return nlohmann::json::json_pointer(std::string(s, n));
23165}
23166
23167// #include <nlohmann/detail/macro_unscope.hpp>
23168
23169
23170// restore clang diagnostic settings
23171#if defined(__clang__)
23172 #pragma clang diagnostic pop
23173#endif
23174
23175// clean up
23176#undef JSON_ASSERT
23177#undef JSON_INTERNAL_CATCH
23178#undef JSON_THROW
23179#undef JSON_PRIVATE_UNLESS_TESTED
23180#undef NLOHMANN_BASIC_JSON_TPL_DECLARATION
23181#undef NLOHMANN_BASIC_JSON_TPL
23182#undef JSON_EXPLICIT
23183#undef NLOHMANN_CAN_CALL_STD_FUNC_IMPL
23184#undef JSON_NO_UNIQUE_ADDRESS
23185
23186#ifndef JSON_TEST_KEEP_MACROS
23187 #undef JSON_CATCH
23188 #undef JSON_TRY
23189 #undef JSON_HAS_CPP_11
23190 #undef JSON_HAS_CPP_14
23191 #undef JSON_HAS_CPP_17
23192 #undef JSON_HAS_CPP_20
23193 #undef JSON_HAS_FILESYSTEM
23194 #undef JSON_HAS_EXPERIMENTAL_FILESYSTEM
23195 #undef JSON_HAS_THREE_WAY_COMPARISON
23196#endif
23197
23198// #include <nlohmann/thirdparty/hedley/hedley_undef.hpp>
23199
23200
23201#undef JSON_HEDLEY_ALWAYS_INLINE
23202#undef JSON_HEDLEY_ARM_VERSION
23203#undef JSON_HEDLEY_ARM_VERSION_CHECK
23204#undef JSON_HEDLEY_ARRAY_PARAM
23205#undef JSON_HEDLEY_ASSUME
23206#undef JSON_HEDLEY_BEGIN_C_DECLS
23207#undef JSON_HEDLEY_CLANG_HAS_ATTRIBUTE
23208#undef JSON_HEDLEY_CLANG_HAS_BUILTIN
23209#undef JSON_HEDLEY_CLANG_HAS_CPP_ATTRIBUTE
23210#undef JSON_HEDLEY_CLANG_HAS_DECLSPEC_DECLSPEC_ATTRIBUTE
23211#undef JSON_HEDLEY_CLANG_HAS_EXTENSION
23212#undef JSON_HEDLEY_CLANG_HAS_FEATURE
23213#undef JSON_HEDLEY_CLANG_HAS_WARNING
23214#undef JSON_HEDLEY_COMPCERT_VERSION
23215#undef JSON_HEDLEY_COMPCERT_VERSION_CHECK
23216#undef JSON_HEDLEY_CONCAT
23217#undef JSON_HEDLEY_CONCAT3
23218#undef JSON_HEDLEY_CONCAT3_EX
23219#undef JSON_HEDLEY_CONCAT_EX
23220#undef JSON_HEDLEY_CONST
23221#undef JSON_HEDLEY_CONSTEXPR
23222#undef JSON_HEDLEY_CONST_CAST
23223#undef JSON_HEDLEY_CPP_CAST
23224#undef JSON_HEDLEY_CRAY_VERSION
23225#undef JSON_HEDLEY_CRAY_VERSION_CHECK
23226#undef JSON_HEDLEY_C_DECL
23227#undef JSON_HEDLEY_DEPRECATED
23228#undef JSON_HEDLEY_DEPRECATED_FOR
23229#undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_CAST_QUAL
23230#undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_
23231#undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED
23232#undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES
23233#undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS
23234#undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNUSED_FUNCTION
23235#undef JSON_HEDLEY_DIAGNOSTIC_POP
23236#undef JSON_HEDLEY_DIAGNOSTIC_PUSH
23237#undef JSON_HEDLEY_DMC_VERSION
23238#undef JSON_HEDLEY_DMC_VERSION_CHECK
23239#undef JSON_HEDLEY_EMPTY_BASES
23240#undef JSON_HEDLEY_EMSCRIPTEN_VERSION
23241#undef JSON_HEDLEY_EMSCRIPTEN_VERSION_CHECK
23242#undef JSON_HEDLEY_END_C_DECLS
23243#undef JSON_HEDLEY_FLAGS
23244#undef JSON_HEDLEY_FLAGS_CAST
23245#undef JSON_HEDLEY_GCC_HAS_ATTRIBUTE
23246#undef JSON_HEDLEY_GCC_HAS_BUILTIN
23247#undef JSON_HEDLEY_GCC_HAS_CPP_ATTRIBUTE
23248#undef JSON_HEDLEY_GCC_HAS_DECLSPEC_ATTRIBUTE
23249#undef JSON_HEDLEY_GCC_HAS_EXTENSION
23250#undef JSON_HEDLEY_GCC_HAS_FEATURE
23251#undef JSON_HEDLEY_GCC_HAS_WARNING
23252#undef JSON_HEDLEY_GCC_NOT_CLANG_VERSION_CHECK
23253#undef JSON_HEDLEY_GCC_VERSION
23254#undef JSON_HEDLEY_GCC_VERSION_CHECK
23255#undef JSON_HEDLEY_GNUC_HAS_ATTRIBUTE
23256#undef JSON_HEDLEY_GNUC_HAS_BUILTIN
23257#undef JSON_HEDLEY_GNUC_HAS_CPP_ATTRIBUTE
23258#undef JSON_HEDLEY_GNUC_HAS_DECLSPEC_ATTRIBUTE
23259#undef JSON_HEDLEY_GNUC_HAS_EXTENSION
23260#undef JSON_HEDLEY_GNUC_HAS_FEATURE
23261#undef JSON_HEDLEY_GNUC_HAS_WARNING
23262#undef JSON_HEDLEY_GNUC_VERSION
23263#undef JSON_HEDLEY_GNUC_VERSION_CHECK
23264#undef JSON_HEDLEY_HAS_ATTRIBUTE
23265#undef JSON_HEDLEY_HAS_BUILTIN
23266#undef JSON_HEDLEY_HAS_CPP_ATTRIBUTE
23267#undef JSON_HEDLEY_HAS_CPP_ATTRIBUTE_NS
23268#undef JSON_HEDLEY_HAS_DECLSPEC_ATTRIBUTE
23269#undef JSON_HEDLEY_HAS_EXTENSION
23270#undef JSON_HEDLEY_HAS_FEATURE
23271#undef JSON_HEDLEY_HAS_WARNING
23272#undef JSON_HEDLEY_IAR_VERSION
23273#undef JSON_HEDLEY_IAR_VERSION_CHECK
23274#undef JSON_HEDLEY_IBM_VERSION
23275#undef JSON_HEDLEY_IBM_VERSION_CHECK
23276#undef JSON_HEDLEY_IMPORT
23277#undef JSON_HEDLEY_INLINE
23278#undef JSON_HEDLEY_INTEL_CL_VERSION
23279#undef JSON_HEDLEY_INTEL_CL_VERSION_CHECK
23280#undef JSON_HEDLEY_INTEL_VERSION
23281#undef JSON_HEDLEY_INTEL_VERSION_CHECK
23282#undef JSON_HEDLEY_IS_CONSTANT
23283#undef JSON_HEDLEY_IS_CONSTEXPR_
23284#undef JSON_HEDLEY_LIKELY
23285#undef JSON_HEDLEY_MALLOC
23286#undef JSON_HEDLEY_MCST_LCC_VERSION
23287#undef JSON_HEDLEY_MCST_LCC_VERSION_CHECK
23288#undef JSON_HEDLEY_MESSAGE
23289#undef JSON_HEDLEY_MSVC_VERSION
23290#undef JSON_HEDLEY_MSVC_VERSION_CHECK
23291#undef JSON_HEDLEY_NEVER_INLINE
23292#undef JSON_HEDLEY_NON_NULL
23293#undef JSON_HEDLEY_NO_ESCAPE
23294#undef JSON_HEDLEY_NO_RETURN
23295#undef JSON_HEDLEY_NO_THROW
23296#undef JSON_HEDLEY_NULL
23297#undef JSON_HEDLEY_PELLES_VERSION
23298#undef JSON_HEDLEY_PELLES_VERSION_CHECK
23299#undef JSON_HEDLEY_PGI_VERSION
23300#undef JSON_HEDLEY_PGI_VERSION_CHECK
23301#undef JSON_HEDLEY_PREDICT
23302#undef JSON_HEDLEY_PRINTF_FORMAT
23303#undef JSON_HEDLEY_PRIVATE
23304#undef JSON_HEDLEY_PUBLIC
23305#undef JSON_HEDLEY_PURE
23306#undef JSON_HEDLEY_REINTERPRET_CAST
23307#undef JSON_HEDLEY_REQUIRE
23308#undef JSON_HEDLEY_REQUIRE_CONSTEXPR
23309#undef JSON_HEDLEY_REQUIRE_MSG
23310#undef JSON_HEDLEY_RESTRICT
23311#undef JSON_HEDLEY_RETURNS_NON_NULL
23312#undef JSON_HEDLEY_SENTINEL
23313#undef JSON_HEDLEY_STATIC_ASSERT
23314#undef JSON_HEDLEY_STATIC_CAST
23315#undef JSON_HEDLEY_STRINGIFY
23316#undef JSON_HEDLEY_STRINGIFY_EX
23317#undef JSON_HEDLEY_SUNPRO_VERSION
23318#undef JSON_HEDLEY_SUNPRO_VERSION_CHECK
23319#undef JSON_HEDLEY_TINYC_VERSION
23320#undef JSON_HEDLEY_TINYC_VERSION_CHECK
23321#undef JSON_HEDLEY_TI_ARMCL_VERSION
23322#undef JSON_HEDLEY_TI_ARMCL_VERSION_CHECK
23323#undef JSON_HEDLEY_TI_CL2000_VERSION
23324#undef JSON_HEDLEY_TI_CL2000_VERSION_CHECK
23325#undef JSON_HEDLEY_TI_CL430_VERSION
23326#undef JSON_HEDLEY_TI_CL430_VERSION_CHECK
23327#undef JSON_HEDLEY_TI_CL6X_VERSION
23328#undef JSON_HEDLEY_TI_CL6X_VERSION_CHECK
23329#undef JSON_HEDLEY_TI_CL7X_VERSION
23330#undef JSON_HEDLEY_TI_CL7X_VERSION_CHECK
23331#undef JSON_HEDLEY_TI_CLPRU_VERSION
23332#undef JSON_HEDLEY_TI_CLPRU_VERSION_CHECK
23333#undef JSON_HEDLEY_TI_VERSION
23334#undef JSON_HEDLEY_TI_VERSION_CHECK
23335#undef JSON_HEDLEY_UNAVAILABLE
23336#undef JSON_HEDLEY_UNLIKELY
23337#undef JSON_HEDLEY_UNPREDICTABLE
23338#undef JSON_HEDLEY_UNREACHABLE
23339#undef JSON_HEDLEY_UNREACHABLE_RETURN
23340#undef JSON_HEDLEY_VERSION
23341#undef JSON_HEDLEY_VERSION_DECODE_MAJOR
23342#undef JSON_HEDLEY_VERSION_DECODE_MINOR
23343#undef JSON_HEDLEY_VERSION_DECODE_REVISION
23344#undef JSON_HEDLEY_VERSION_ENCODE
23345#undef JSON_HEDLEY_WARNING
23346#undef JSON_HEDLEY_WARN_UNUSED_RESULT
23347#undef JSON_HEDLEY_WARN_UNUSED_RESULT_MSG
23348#undef JSON_HEDLEY_FALL_THROUGH
23349
23350
23351
23352#endif // INCLUDE_NLOHMANN_JSON_HPP_
type
Definition Gameobj.h:11
unsigned short uint16_t
Definition stdint.h:79
signed __int64 int64_t
Definition stdint.h:89
unsigned int uint32_t
Definition stdint.h:80
unsigned char uint8_t
Definition stdint.h:78
unsigned __int64 uint64_t
Definition stdint.h:90
#define C
Definition stb_vorbis.c:5132
result
Definition core_func_integer.cpp:18
#define u
Definition core_func_integer_find_lsb.cpp:179
genType add(genType const &a, genType const &b)
Definition core_setup_force_size_t_length.cpp:6
return(unsigned char) __builtin_ia32_ktestzsi(__A
#define or
Definition iso646.h:39
#define true
Definition stdbool.h:38
#define false
Definition stdbool.h:39
#define bool
Definition stdbool.h:33
__PTRDIFF_TYPE__ ptrdiff_t
Definition stddef.h:146
__SIZE_TYPE__ size_t
Definition stddef.h:215
#define exp(z)
Definition tgmath.h:73
EGLStreamKHR stream
Definition eglext.h:297
typedef void(EGLAPIENTRYP PFNEGLSETBLOBCACHEFUNCSANDROIDPROC)(EGLDisplay dpy
EGLImageKHR EGLint * name
Definition eglext.h:636
EGLSurface EGLint EGLint y
Definition eglext.h:713
EGLContext EGLenum EGLClientBuffer buffer
Definition eglext.h:149
EGLSurface EGLint x
Definition eglext.h:713
EGLContext EGLenum target
Definition eglext.h:149
EGLSetBlobFuncANDROID EGLGetBlobFuncANDROID get
Definition eglext.h:375
GLclampf ref
Definition gl2ext.h:1918
GLint GLint GLint GLint GLint w
Definition gl2ext.h:1595
GLsizei size
Definition gl2ext.h:1935
GLint GLenum GLsizei GLsizei GLsizei GLint GLenum format
Definition gl2ext.h:1121
GLint index
Definition gl2ext.h:1492
GLsizei GLsizei GLchar * source
Definition gl2ext.h:1333
GLenum GLuint GLenum GLsizei const GLchar * message
Definition gl2ext.h:186
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition gl2ext.h:1124
GLuint object
Definition gl2ext.h:1436
GLsizei GLsizei GLenum GLvoid * binary
Definition gl2ext.h:1059
GLenum GLuint GLenum GLsizei const GLchar * buf
Definition gl2ext.h:1199
GLint first
Definition gl2ext.h:1298
GLintptr offset
Definition gl2ext.h:1470
GLfloat f
Definition glad.h:2901
const GLdouble * v
Definition glad.h:1495
GLuint res
Definition glad.h:3616
GLenum GLsizei len
Definition glad.h:2989
GLuint GLuint end
Definition glad.h:1185
GLsizei const GLchar ** string
Definition glad.h:1426
GLboolean GLboolean GLboolean b
Definition glad.h:1629
GLenum GLint * range
Definition glad.h:2898
GLuint GLfloat * val
Definition glad.h:1976
GLuint GLuint num
Definition glad.h:3631
GLboolean r
Definition glad.h:1629
GLuint start
Definition glad.h:1185
GLboolean GLboolean GLboolean GLboolean a
Definition glad.h:1629
GLenum void ** pointer
Definition glad.h:1414
unsigned char byte
Definition rlgl.h:192
bool
Definition raylib.h:192
#define is
Definition Monobehavior.h:46
A TOML array.
Definition array.h:265
TOML_NODISCARD iterator begin() noexcept
Returns an iterator to the first element.
Definition array.h:790
TOML_NODISCARD iterator end() noexcept
Returns an iterator to one-past-the-last element.
Definition array.h:811
TOML_NODISCARD size_t size() const noexcept
Returns the number of elements in the array.
Definition array.h:1073
a class to store JSON values
Definition json.hpp:18200
ValueType & get_to(ValueType &v) const
Definition json.hpp:19901
void insert(const_iterator first, const_iterator last)
inserts range of elements into object
Definition json.hpp:21428
detail::parser_callback_t< basic_json > parser_callback_t
per-element parser callback type
Definition json.hpp:18896
iteration_proxy< iterator > items() noexcept
helper to access iterator member functions in range-based for
Definition json.hpp:20926
const_reverse_iterator crbegin() const noexcept
returns a const reverse iterator to the last element
Definition json.hpp:20889
static JSON_HEDLEY_WARN_UNUSED_RESULT basic_json from_bjdata(const T *ptr, std::size_t len, const bool strict=true, const bool allow_exceptions=true)
Definition json.hpp:22478
const_reference operator[](const json_pointer &ptr) const
access specified element via JSON Pointer
Definition json.hpp:22577
reference operator[](const json_pointer &ptr)
access specified element via JSON Pointer
Definition json.hpp:22563
friend bool operator==(const_reference lhs, ScalarType rhs) noexcept
comparison: equal
Definition json.hpp:21701
constexpr bool is_number_float() const noexcept
return whether value is a floating-point number
Definition json.hpp:19440
const_reference operator[](T *key) const
Definition json.hpp:20255
NumberIntegerType number_integer_t
a type for a number (integer)
Definition json.hpp:18457
friend bool operator==(const_reference lhs, const_reference rhs) noexcept
comparison: equal
Definition json.hpp:21621
void update(const_reference j, bool merge_objects=false)
updates a JSON object from another object, overwriting existing keys
Definition json.hpp:21453
static bool sax_parse(InputType &&i, SAX *sax, input_format_t format=input_format_t::json, const bool strict=true, const bool ignore_comments=false)
generate SAX events
Definition json.hpp:22028
static std::vector< std::uint8_t > to_bjdata(const basic_json &j, const bool use_size=false, const bool use_type=false)
create a BJData serialization of a given JSON value
Definition json.hpp:22230
::nlohmann::json_pointer< StringType > json_pointer
JSON Pointer, see nlohmann::json_pointer.
Definition json.hpp:18266
ReferenceType get_ref()
get a reference value (implicit)
Definition json.hpp:19924
static JSON_HEDLEY_WARN_UNUSED_RESULT basic_json parse(InputType &&i, const parser_callback_t cb=nullptr, const bool allow_exceptions=true, const bool ignore_comments=false)
deserialize from a compatible input
Definition json.hpp:21961
reference emplace_back(Args &&... args)
add an object to an array
Definition json.hpp:21254
json_sax< basic_json > json_sax_t
SAX interface type, see nlohmann::json_sax.
Definition json.hpp:18278
basic_json(const value_t v)
create an empty value with a given type
Definition json.hpp:18909
size_type max_size() const noexcept
returns the maximum possible number of elements
Definition json.hpp:21028
static JSON_HEDLEY_WARN_UNUSED_RESULT basic_json diff(const basic_json &source, const basic_json &target, const std::string &path="")
creates a diff as a JSON patch
Definition json.hpp:22919
iterator find(KeyType &&key)
find an element in a JSON object
Definition json.hpp:20723
static JSON_HEDLEY_WARN_UNUSED_RESULT basic_json from_bjdata(detail::span_input_adapter &&i, const bool strict=true, const bool allow_exceptions=true)
Definition json.hpp:22486
static std::vector< std::uint8_t > to_bson(const basic_json &j)
create a BSON serialization of a given JSON value
Definition json.hpp:22257
value_type & reference
the type of an element reference
Definition json.hpp:18311
void erase(const size_type idx)
remove element from a JSON array given an index
Definition json.hpp:20663
const_reverse_iterator crend() const noexcept
returns a const reverse iterator to one before the first
Definition json.hpp:20896
const_reference at(const typename object_t::key_type &key) const
access specified object element with bounds checking
Definition json.hpp:20114
reference at(const typename object_t::key_type &key)
access specified object element with bounds checking
Definition json.hpp:20076
iterator begin() noexcept
returns an iterator to the first element
Definition json.hpp:20811
binary_t & get_binary()
get a binary value
Definition json.hpp:19995
basic_json(InputIT first, InputIT last)
construct a JSON container given an iterator range
Definition json.hpp:19123
static std::vector< std::uint8_t > to_msgpack(const basic_json &j)
create a MessagePack serialization of a given JSON value
Definition json.hpp:22180
friend bool operator==(ScalarType lhs, const_reference rhs) noexcept
comparison: equal
Definition json.hpp:21710
basic_json(const JsonRef &ref)
Definition json.hpp:19233
static std::vector< std::uint8_t > to_cbor(const basic_json &j)
create a CBOR serialization of a given JSON value
Definition json.hpp:22157
basic_json & operator=(basic_json other) noexcept(std::is_nothrow_move_constructible< value_t >::value &&std::is_nothrow_move_assignable< value_t >::value &&std::is_nothrow_move_constructible< json_value >::value &&std::is_nothrow_move_assignable< json_value >::value)
copy assignment
Definition json.hpp:19322
static JSON_HEDLEY_WARN_UNUSED_RESULT basic_json array(initializer_list_t init={})
explicitly create an array from an initializer list
Definition json.hpp:19095
const_reverse_iterator rend() const noexcept
returns an iterator to the reverse-end
Definition json.hpp:20882
const_iterator cend() const noexcept
returns an iterator to one past the last element
Definition json.hpp:20852
reference back()
access the last element
Definition json.hpp:20449
const binary_t & get_binary() const
get a binary value
Definition json.hpp:20007
static bool accept(InputType &&i, const bool ignore_comments=false)
check if the input is valid JSON
Definition json.hpp:22001
static void to_bjdata(const basic_json &j, detail::output_adapter< char > o, const bool use_size=false, const bool use_type=false)
create a BJData serialization of a given JSON value
Definition json.hpp:22249
StringType string_t
a type for a string
Definition json.hpp:18449
size_type size() const noexcept
returns the number of elements
Definition json.hpp:20989
void push_back(const basic_json &val)
add an object to an array
Definition json.hpp:21166
reference at(KeyType &&key)
access specified object element with bounds checking
Definition json.hpp:20096
static JSON_HEDLEY_WARN_UNUSED_RESULT basic_json meta()
returns version information on the library
Definition json.hpp:18350
ValueType value(const json_pointer &ptr, const ValueType &default_value) const
access specified object element via JSON Pointer with default value
Definition json.hpp:20389
ObjectType< StringType, basic_json, default_object_comparator_t, AllocatorType< std::pair< const StringType, basic_json > > > object_t
a type for an object
Definition json.hpp:18441
std::size_t size_type
a type to represent container sizes
Definition json.hpp:18318
ValueType & get_to(ValueType &v) const noexcept(noexcept(JSONSerializer< ValueType >::from_json(std::declval< const basic_json_t & >(), v)))
get a value (explicit)
Definition json.hpp:19888
std::ptrdiff_t difference_type
a type to represent differences between iterators
Definition json.hpp:18316
static JSON_HEDLEY_WARN_UNUSED_RESULT basic_json binary(const typename binary_t::container_type &init)
explicitly create a binary array (without subtype)
Definition json.hpp:19051
reference operator+=(basic_json &&val)
add an object to an array
Definition json.hpp:21158
basic_json(const BasicJsonType &val)
create a JSON value from an existing one
Definition json.hpp:18943
typename std::allocator_traits< allocator_type >::const_pointer const_pointer
the type of an element const pointer
Definition json.hpp:18326
static JSON_HEDLEY_WARN_UNUSED_RESULT basic_json from_bson(IteratorType first, IteratorType last, const bool strict=true, const bool allow_exceptions=true)
create a JSON value from an input in BSON format
Definition json.hpp:22518
size_type count(const typename object_t::key_type &key) const
returns the number of occurrences of a key in a JSON object
Definition json.hpp:20753
static JSON_HEDLEY_WARN_UNUSED_RESULT basic_json from_bjdata(InputType &&i, const bool strict=true, const bool allow_exceptions=true)
create a JSON value from an input in BJData format
Definition json.hpp:22450
typename std::allocator_traits< allocator_type >::pointer pointer
the type of an element pointer
Definition json.hpp:18324
static JSON_HEDLEY_WARN_UNUSED_RESULT basic_json from_cbor(InputType &&i, const bool strict=true, const bool allow_exceptions=true, const cbor_tag_handler_t tag_handler=cbor_tag_handler_t::error)
create a JSON value from an input in CBOR format
Definition json.hpp:22282
BooleanType boolean_t
a type for a boolean
Definition json.hpp:18453
void push_back(initializer_list_t init)
add an object to an object
Definition json.hpp:21229
string_t dump(const int indent=-1, const char indent_char=' ', const bool ensure_ascii=false, const error_handler_t error_handler=error_handler_t::strict) const
serialization
Definition json.hpp:19362
reference operator[](typename object_t::key_type key)
access specified object element
Definition json.hpp:20211
static bool accept(IteratorType first, IteratorType last, const bool ignore_comments=false)
check if the input is valid JSON
Definition json.hpp:22010
std::decay< ValueType >::type value(KeyType &&key, ValueType &&default_value) const
access specified object element with default value
Definition json.hpp:20357
IteratorType erase(IteratorType pos)
remove element given an iterator
Definition json.hpp:20470
const_iterator find(const typename object_t::key_type &key) const
find an element in a JSON object
Definition json.hpp:20707
static void to_bson(const basic_json &j, detail::output_adapter< std::uint8_t > o)
create a BSON serialization of a given JSON value
Definition json.hpp:22266
friend bool operator!=(const_reference lhs, ScalarType rhs) noexcept
comparison: not equal
Definition json.hpp:21726
static JSON_HEDLEY_WARN_UNUSED_RESULT basic_json from_bson(InputType &&i, const bool strict=true, const bool allow_exceptions=true)
create a JSON value from an input in BSON format
Definition json.hpp:22503
constexpr bool is_structured() const noexcept
return whether type is structured
Definition json.hpp:19398
friend bool operator<=(ScalarType lhs, const_reference rhs) noexcept
comparison: less than or equal
Definition json.hpp:21854
const_iterator begin() const noexcept
returns an iterator to the first element
Definition json.hpp:20820
void update(const_iterator first, const_iterator last, bool merge_objects=false)
updates a JSON object from another object, overwriting existing keys
Definition json.hpp:21460
friend bool operator<(const_reference lhs, ScalarType rhs) noexcept
comparison: less than
Definition json.hpp:21820
reference at(size_type idx)
access specified array element with bounds checking
Definition json.hpp:20030
static JSON_HEDLEY_WARN_UNUSED_RESULT basic_json binary(typename binary_t::container_type &&init, typename binary_t::subtype_type subtype)
explicitly create a binary array (with subtype)
Definition json.hpp:19084
reference front()
access the first element
Definition json.hpp:20435
constexpr bool is_primitive() const noexcept
return whether type is primitive
Definition json.hpp:19391
constexpr bool is_number_unsigned() const noexcept
return whether value is an unsigned integer number
Definition json.hpp:19433
static void to_cbor(const basic_json &j, detail::output_adapter< char > o)
create a CBOR serialization of a given JSON value
Definition json.hpp:22173
void swap(object_t &other)
exchanges the values
Definition json.hpp:21551
constexpr bool is_object() const noexcept
return whether value is an object
Definition json.hpp:19447
bool contains(KeyType &&key) const
check the existence of an element in a JSON object
Definition json.hpp:20780
reference operator[](KeyType &&key)
access specified object element
Definition json.hpp:20264
const_reference front() const
access the first element
Definition json.hpp:20442
constexpr value_t type() const noexcept
return the type of the JSON value (explicit)
Definition json.hpp:19384
NumberFloatType number_float_t
a type for a number (floating-point)
Definition json.hpp:18465
json_reverse_iterator< typename basic_json::iterator > reverse_iterator
a reverse iterator for a basic_json container
Definition json.hpp:18333
friend std::ostream & operator<<(std::ostream &o, const basic_json &j)
serialize to stream
Definition json.hpp:21920
friend bool operator<=(const_reference lhs, const_reference rhs) noexcept
comparison: less than or equal
Definition json.hpp:21836
bool empty() const noexcept
checks whether the container is empty.
Definition json.hpp:20950
basic_json(const basic_json &other)
copy constructor
Definition json.hpp:19237
~basic_json() noexcept
destructor
Definition json.hpp:19343
const_iterator find(KeyType &&key) const
find an element in a JSON object
Definition json.hpp:20739
static std::vector< std::uint8_t > to_ubjson(const basic_json &j, const bool use_size=false, const bool use_type=false)
create a UBJSON serialization of a given JSON value
Definition json.hpp:22203
basic_json(basic_json &&other) noexcept
move constructor
Definition json.hpp:19305
friend bool operator>(ScalarType lhs, const_reference rhs) noexcept
comparison: greater than
Definition json.hpp:21879
bool contains(const typename object_t::key_type &key) const
check the existence of an element in a JSON object
Definition json.hpp:20771
static void to_ubjson(const basic_json &j, detail::output_adapter< char > o, const bool use_size=false, const bool use_type=false)
create a UBJSON serialization of a given JSON value
Definition json.hpp:22222
friend bool operator!=(const_reference lhs, const_reference rhs) noexcept
comparison: not equal
Definition json.hpp:21717
iterator insert(const_iterator pos, size_type cnt, const basic_json &val)
inserts copies of element into array
Definition json.hpp:21357
friend bool operator<(ScalarType lhs, const_reference rhs) noexcept
comparison: less than
Definition json.hpp:21829
json_value m_value
the value of the current element
Definition json.hpp:22140
void swap(typename binary_t::container_type &other)
exchanges the values
Definition json.hpp:21596
friend bool operator>=(const_reference lhs, const_reference rhs) noexcept
comparison: greater than or equal
Definition json.hpp:21886
void swap(array_t &other)
exchanges the values
Definition json.hpp:21536
reverse_iterator rend() noexcept
returns an iterator to the reverse-end
Definition json.hpp:20875
static JSON_HEDLEY_WARN_UNUSED_RESULT basic_json binary(const typename binary_t::container_type &init, typename binary_t::subtype_type subtype)
explicitly create a binary array (with subtype)
Definition json.hpp:19062
static iteration_proxy< iterator > iterator_wrapper(reference ref) noexcept
wrapper to access iterator member functions in range-based for
Definition json.hpp:20908
std::less< StringType > default_object_comparator_t
default object key comparator type The actual object key comparator type (object_comparator_t) may be...
Definition json.hpp:18432
ReferenceType get_ref() const
get a reference value (implicit)
Definition json.hpp:19935
const_reference at(KeyType &&key) const
access specified object element with bounds checking
Definition json.hpp:20134
iterator insert(const_iterator pos, const_iterator first, const_iterator last)
inserts range of elements into array
Definition json.hpp:21377
auto get() noexcept -> decltype(std::declval< basic_json_t & >().template get_ptr< PointerType >())
get a pointer value (explicit)
Definition json.hpp:19875
const_reference at(const json_pointer &ptr) const
access specified element via JSON Pointer
Definition json.hpp:22605
const_iterator end() const noexcept
returns an iterator to one past the last element
Definition json.hpp:20845
void merge_patch(const basic_json &apply_patch)
applies a JSON Merge Patch
Definition json.hpp:23062
auto get_ptr() noexcept -> decltype(std::declval< basic_json_t & >().get_impl_ptr(std::declval< PointerType >()))
get a pointer value (implicit)
Definition json.hpp:19635
iteration_proxy< const_iterator > items() const noexcept
helper to access iterator member functions in range-based for
Definition json.hpp:20933
iterator insert(const_iterator pos, initializer_list_t ilist)
inserts elements from initializer list into array
Definition json.hpp:21408
ArrayType< basic_json, AllocatorType< basic_json > > array_t
a type for an array
Definition json.hpp:18445
Array get_to(T(&v)[N]) const noexcept(noexcept(JSONSerializer< Array >::from_json(std::declval< const basic_json_t & >(), v)))
Definition json.hpp:19912
friend bool operator>(const_reference lhs, const_reference rhs) noexcept
comparison: greater than
Definition json.hpp:21861
const_reference operator[](KeyType &&key) const
access specified object element
Definition json.hpp:20288
IteratorType erase(IteratorType first, IteratorType last)
remove elements given an iterator range
Definition json.hpp:20540
constexpr bool is_boolean() const noexcept
return whether value is a boolean
Definition json.hpp:19412
iterator end() noexcept
returns an iterator to one past the last element
Definition json.hpp:20836
void swap(reference other) noexcept(std::is_nothrow_move_constructible< value_t >::value &&std::is_nothrow_move_assignable< value_t >::value &&std::is_nothrow_move_constructible< json_value >::value &&std::is_nothrow_move_assignable< json_value >::value)
exchanges the values
Definition json.hpp:21507
void clear() noexcept
clears the contents
Definition json.hpp:21072
friend bool operator>=(ScalarType lhs, const_reference rhs) noexcept
comparison: greater than or equal
Definition json.hpp:21904
static JSON_HEDLEY_WARN_UNUSED_RESULT basic_json from_msgpack(IteratorType first, IteratorType last, const bool strict=true, const bool allow_exceptions=true)
create a JSON value from an input in MessagePack format
Definition json.hpp:22356
constexpr bool is_binary() const noexcept
return whether value is a binary array
Definition json.hpp:19468
static JSON_HEDLEY_WARN_UNUSED_RESULT basic_json object(initializer_list_t init={})
explicitly create an object from an initializer list
Definition json.hpp:19103
iterator insert(const_iterator pos, basic_json &&val)
inserts element into array
Definition json.hpp:21350
static JSON_HEDLEY_WARN_UNUSED_RESULT basic_json from_ubjson(IteratorType first, IteratorType last, const bool strict=true, const bool allow_exceptions=true)
create a JSON value from an input in UBJSON format
Definition json.hpp:22410
reference operator[](size_type idx)
access specified array element
Definition json.hpp:20152
friend bool operator>(const_reference lhs, ScalarType rhs) noexcept
comparison: greater than
Definition json.hpp:21870
static void to_bson(const basic_json &j, detail::output_adapter< char > o)
create a BSON serialization of a given JSON value
Definition json.hpp:22273
std::decay< ValueType >::type value(const char *key, ValueType &&default_value) const
Definition json.hpp:20340
string_t value(KeyType &&key, const char *default_value) const
access specified object element with default value
Definition json.hpp:20380
reference at(const json_pointer &ptr)
access specified element via JSON Pointer
Definition json.hpp:22591
void swap(binary_t &other)
exchanges the values
Definition json.hpp:21581
iter_impl< basic_json > iterator
an iterator for a basic_json container
Definition json.hpp:18329
json_reverse_iterator< typename basic_json::const_iterator > const_reverse_iterator
a const reverse iterator for a basic_json container
Definition json.hpp:18335
static JSON_HEDLEY_WARN_UNUSED_RESULT basic_json from_ubjson(InputType &&i, const bool strict=true, const bool allow_exceptions=true)
create a JSON value from an input in UBJSON format
Definition json.hpp:22395
friend bool operator!=(ScalarType lhs, const_reference rhs) noexcept
comparison: not equal
Definition json.hpp:21735
static void to_ubjson(const basic_json &j, detail::output_adapter< std::uint8_t > o, const bool use_size=false, const bool use_type=false)
create a UBJSON serialization of a given JSON value
Definition json.hpp:22214
const_reverse_iterator rbegin() const noexcept
returns an iterator to the reverse-beginning
Definition json.hpp:20868
string_t value(const char *key, const char *default_value) const
Definition json.hpp:20345
size_type count(KeyType &&key) const
returns the number of occurrences of a key in a JSON object
Definition json.hpp:20763
void swap(string_t &other)
exchanges the values
Definition json.hpp:21566
const_reference back() const
access the last element
Definition json.hpp:20458
friend bool operator<(const_reference lhs, const_reference rhs) noexcept
comparison: less than
Definition json.hpp:21742
static JSON_HEDLEY_WARN_UNUSED_RESULT basic_json binary(typename binary_t::container_type &&init)
explicitly create a binary array
Definition json.hpp:19073
constexpr bool is_string() const noexcept
return whether value is a string
Definition json.hpp:19461
constexpr bool is_array() const noexcept
return whether value is an array
Definition json.hpp:19454
iterator insert_iterator(const_iterator pos, Args &&... args)
Definition json.hpp:21311
basic_json flatten() const
return flattened JSON value
Definition json.hpp:22619
friend bool operator>=(const_reference lhs, ScalarType rhs) noexcept
comparison: greater than or equal
Definition json.hpp:21895
JSON_HEDLEY_RETURNS_NON_NULL const char * type_name() const noexcept
return the type as string
Definition json.hpp:22104
void push_back(basic_json &&val)
add an object to an array
Definition json.hpp:21133
static JSON_HEDLEY_WARN_UNUSED_RESULT basic_json from_cbor(IteratorType first, IteratorType last, const bool strict=true, const bool allow_exceptions=true, const cbor_tag_handler_t tag_handler=cbor_tag_handler_t::error)
create a JSON value from an input in CBOR format
Definition json.hpp:22298
reference operator[](T *key)
Definition json.hpp:20249
constexpr bool is_number() const noexcept
return whether value is a number
Definition json.hpp:19419
friend std::ostream & operator>>(const basic_json &j, std::ostream &o)
serialize to stream
Definition json.hpp:21942
reference operator+=(initializer_list_t init)
add an object to an object
Definition json.hpp:21245
constexpr bool is_number_integer() const noexcept
return whether value is an integer number
Definition json.hpp:19426
std::initializer_list< detail::json_ref< basic_json > > initializer_list_t
helper type for initializer lists of basic_json values
Definition json.hpp:18274
static void to_cbor(const basic_json &j, detail::output_adapter< std::uint8_t > o)
create a CBOR serialization of a given JSON value
Definition json.hpp:22166
detail::value_t value_t
Definition json.hpp:18264
size_type erase(KeyType &&key)
remove element from a JSON object given a key
Definition json.hpp:20656
friend class ::nlohmann::detail::parser
Definition json.hpp:18210
static void to_msgpack(const basic_json &j, detail::output_adapter< char > o)
create a MessagePack serialization of a given JSON value
Definition json.hpp:22196
const_reference operator[](const typename object_t::key_type &key) const
access specified object element
Definition json.hpp:20233
detail::actual_object_comparator_t< basic_json > object_comparator_t
object key comparator type
Definition json.hpp:18473
basic_json(std::nullptr_t=nullptr) noexcept
create a null object
Definition json.hpp:18917
static JSON_HEDLEY_WARN_UNUSED_RESULT basic_json from_bjdata(IteratorType first, IteratorType last, const bool strict=true, const bool allow_exceptions=true)
create a JSON value from an input in BJData format
Definition json.hpp:22465
const_reference operator[](size_type idx) const
access specified array element
Definition json.hpp:20198
AllocatorType< basic_json > allocator_type
the allocator type
Definition json.hpp:18321
nlohmann::byte_container_with_subtype< BinaryType > binary_t
a type for a packed binary type
Definition json.hpp:18469
JSONSerializer< T, SFINAE > json_serializer
Definition json.hpp:18268
void push_back(const typename object_t::value_type &val)
add an object to an object
Definition json.hpp:21198
static JSON_HEDLEY_WARN_UNUSED_RESULT basic_json parse(IteratorType first, IteratorType last, const parser_callback_t cb=nullptr, const bool allow_exceptions=true, const bool ignore_comments=false)
deserialize from a pair of character iterators
Definition json.hpp:21975
bool contains(const json_pointer &ptr) const
check the existence of an element in a JSON object given a JSON pointer
Definition json.hpp:20787
static JSON_HEDLEY_WARN_UNUSED_RESULT basic_json from_msgpack(InputType &&i, const bool strict=true, const bool allow_exceptions=true)
create a JSON value from an input in MessagePack format
Definition json.hpp:22341
basic_json patch(const basic_json &json_patch) const
applies a JSON patch
Definition json.hpp:22644
string_t value(const typename object_t::key_type &key, const char *default_value) const
access specified object element with default value
Definition json.hpp:20329
basic_json(CompatibleType &&val) noexcept(noexcept(//NOLINT(bugprone-forwarding-reference-overload, bugprone-exception-escape) JSONSerializer< U >::to_json(std::declval< basic_json_t & >(), std::forward< CompatibleType >(val))))
create a JSON value from compatible types
Definition json.hpp:18929
basic_json unflatten() const
unflatten a previously flattened JSON value
Definition json.hpp:22628
NumberUnsignedType number_unsigned_t
a type for a number (unsigned)
Definition json.hpp:18461
iterator find(const typename object_t::key_type &key)
find an element in a JSON object
Definition json.hpp:20693
reference operator+=(const typename object_t::value_type &val)
add an object to an object
Definition json.hpp:21221
const_iterator cbegin() const noexcept
returns a const iterator to the first element
Definition json.hpp:20827
friend bool operator<=(const_reference lhs, ScalarType rhs) noexcept
comparison: less than or equal
Definition json.hpp:21845
std::decay< ValueType >::type value(const KeyType &key, ValueType &&default_value) const
access specified object element with default value
Definition json.hpp:20308
friend std::istream & operator>>(std::istream &i, basic_json &j)
deserialize from stream
Definition json.hpp:22089
basic_json(initializer_list_t init, bool type_deduction=true, value_t manual_type=value_t::array)
create a container (array or object) from an initializer list
Definition json.hpp:18995
const_reference at(size_type idx) const
access specified array element with bounds checking
Definition json.hpp:20053
iterator insert(const_iterator pos, const basic_json &val)
inserts element into array
Definition json.hpp:21330
constexpr bool is_discarded() const noexcept
return whether value is discarded
Definition json.hpp:19475
constexpr bool is_null() const noexcept
return whether value is null
Definition json.hpp:19405
friend void swap(reference left, reference right) noexcept(std::is_nothrow_move_constructible< value_t >::value &&std::is_nothrow_move_assignable< value_t >::value &&std::is_nothrow_move_constructible< json_value >::value &&std::is_nothrow_move_assignable< json_value >::value)
exchanges the values
Definition json.hpp:21524
static void to_bjdata(const basic_json &j, detail::output_adapter< std::uint8_t > o, const bool use_size=false, const bool use_type=false)
create a BJData serialization of a given JSON value
Definition json.hpp:22241
auto get() const noexcept(noexcept(std::declval< const basic_json_t & >().template get_impl< ValueType >(detail::priority_tag< 4 > {}))) -> decltype(std::declval< const basic_json_t & >().template get_impl< ValueType >(detail::priority_tag< 4 > {}))
get a (pointer) value (explicit)
Definition json.hpp:19834
std::pair< iterator, bool > emplace(Args &&... args)
add an object to an object if key does not exist
Definition json.hpp:21279
static void to_msgpack(const basic_json &j, detail::output_adapter< std::uint8_t > o)
create a MessagePack serialization of a given JSON value
Definition json.hpp:22189
reference operator+=(const basic_json &val)
add an object to an array
Definition json.hpp:21190
size_type erase(const typename object_t::key_type &key)
remove element from a JSON object given a key
Definition json.hpp:20645
basic_json(size_type cnt, const basic_json &val)
construct an array with count copies of given value
Definition json.hpp:19110
static allocator_type get_allocator()
returns the allocator associated with the container
Definition json.hpp:18342
constexpr auto get_ptr() const noexcept -> decltype(std::declval< const basic_json_t & >().get_impl_ptr(std::declval< PointerType >()))
get a pointer value (implicit)
Definition json.hpp:19646
reverse_iterator rbegin() noexcept
returns an iterator to the reverse-beginning
Definition json.hpp:20861
an internal type for a backed binary type
Definition json.hpp:5267
byte_container_with_subtype(const container_type &b, subtype_type subtype_) noexcept(noexcept(container_type(b)))
Definition json.hpp:5288
BinaryType container_type
Definition json.hpp:5269
byte_container_with_subtype(const container_type &b) noexcept(noexcept(container_type(b)))
Definition json.hpp:5278
byte_container_with_subtype(container_type &&b) noexcept(noexcept(container_type(std::move(b))))
Definition json.hpp:5283
bool operator!=(const byte_container_with_subtype &rhs) const
Definition json.hpp:5307
void clear_subtype() noexcept
clears the binary subtype
Definition json.hpp:5336
byte_container_with_subtype() noexcept(noexcept(container_type()))
Definition json.hpp:5273
byte_container_with_subtype(container_type &&b, subtype_type subtype_) noexcept(noexcept(container_type(std::move(b))))
Definition json.hpp:5295
constexpr bool has_subtype() const noexcept
return whether the value has a subtype
Definition json.hpp:5329
void set_subtype(subtype_type subtype_) noexcept
sets the binary subtype
Definition json.hpp:5314
constexpr subtype_type subtype() const noexcept
return the binary subtype
Definition json.hpp:5322
std::uint64_t subtype_type
Definition json.hpp:5270
bool operator==(const byte_container_with_subtype &rhs) const
Definition json.hpp:5301
deserialization of CBOR, MessagePack, and UBJSON values
Definition json.hpp:8529
binary_reader & operator=(const binary_reader &)=delete
binary_reader(InputAdapterType &&adapter, const input_format_t format=input_format_t::json) noexcept
create a binary reader
Definition json.hpp:8545
binary_reader & operator=(binary_reader &&)=default
binary_reader(const binary_reader &)=delete
bool sax_parse(const input_format_t format, json_sax_t *sax_, const bool strict=true, const cbor_tag_handler_t tag_handler=cbor_tag_handler_t::error)
Definition json.hpp:8566
binary_reader(binary_reader &&)=default
general exception of the basic_json class
Definition json.hpp:3867
const int id
the id of the exception
Definition json.hpp:3876
static std::string diagnostics(std::nullptr_t)
Definition json.hpp:3887
static std::string diagnostics(const BasicJsonType *leaf_element)
Definition json.hpp:3893
static std::string name(const std::string &ename, int id_)
Definition json.hpp:3882
const char * what() const noexcept override
returns the explanatory string
Definition json.hpp:3870
exception indicating errors with iterators
Definition json.hpp:4018
static invalid_iterator create(int id_, const std::string &what_arg, BasicJsonContext context)
Definition json.hpp:4021
a template for a bidirectional iterator for the basic_json class This class implements a both iterato...
Definition json.hpp:12054
bool operator<(const iter_impl &other) const
comparison: smaller
Definition json.hpp:12517
iter_impl operator-(difference_type i) const
subtract from iterator
Definition json.hpp:12647
bool operator!=(const IterImpl &other) const
comparison: not equal
Definition json.hpp:12508
void set_end() noexcept
set the iterator past the last value
Definition json.hpp:12244
typename BasicJsonType::difference_type difference_type
a type to represent differences between iterators
Definition json.hpp:12081
iter_impl & operator--()
pre-decrement (–it)
Definition json.hpp:12431
difference_type operator-(const iter_impl &other) const
return difference
Definition json.hpp:12658
iter_impl & operator=(const iter_impl< const BasicJsonType > &other) noexcept
converting assignment
Definition json.hpp:12163
typename std::conditional< std::is_const< BasicJsonType >::value, typename BasicJsonType::const_reference, typename BasicJsonType::reference >::type reference
defines a reference to the type iterated over (value_type)
Definition json.hpp:12090
reference operator*() const
return a reference to the value pointed to by the iterator
Definition json.hpp:12283
iter_impl(iter_impl &&) noexcept=default
bool operator>=(const iter_impl &other) const
comparison: greater than or equal
Definition json.hpp:12570
typename std::conditional< std::is_const< BasicJsonType >::value, typename BasicJsonType::const_pointer, typename BasicJsonType::pointer >::type pointer
defines a pointer to the type iterated over (value_type)
Definition json.hpp:12085
iter_impl & operator=(const iter_impl< typename std::remove_const< BasicJsonType >::type > &other) noexcept
converting assignment
Definition json.hpp:12188
pointer operator->() const
dereference the iterator
Definition json.hpp:12327
iter_impl(const iter_impl< const BasicJsonType > &other) noexcept
const copy constructor
Definition json.hpp:12153
iter_impl(const iter_impl< typename std::remove_const< BasicJsonType >::type > &other) noexcept
converting constructor
Definition json.hpp:12178
internal_iterator< typename std::remove_const< BasicJsonType >::type > m_it
the actual iterator of the associated instance
Definition json.hpp:12750
iter_impl operator+(difference_type i) const
add to iterator
Definition json.hpp:12625
friend iter_impl operator+(difference_type i, const iter_impl &it)
addition of distance and iterator
Definition json.hpp:12636
const object_t::key_type & key() const
return the key of an object iterator
Definition json.hpp:12725
bool operator==(const IterImpl &other) const
comparison: equal
Definition json.hpp:12472
bool operator>(const iter_impl &other) const
comparison: greater than
Definition json.hpp:12561
typename BasicJsonType::value_type value_type
the type of the values when the iterator is dereferenced
Definition json.hpp:12079
reference value() const
return the value of an iterator
Definition json.hpp:12741
iter_impl & operator++()
pre-increment (++it)
Definition json.hpp:12380
reference operator[](difference_type n) const
access to successor
Definition json.hpp:12687
bool operator<=(const iter_impl &other) const
comparison: less than or equal
Definition json.hpp:12552
iter_impl operator++(int) &
post-increment (it++)
Definition json.hpp:12369
std::bidirectional_iterator_tag iterator_category
Definition json.hpp:12076
iter_impl operator--(int) &
post-decrement (it–)
Definition json.hpp:12420
iter_impl & operator+=(difference_type i)
add to iterator
Definition json.hpp:12579
iter_impl & operator-=(difference_type i)
subtract from iterator
Definition json.hpp:12616
Definition json.hpp:13780
json_ref(json_ref &&) noexcept=default
value_type const & operator*() const
Definition json.hpp:13819
BasicJsonType value_type
Definition json.hpp:13782
json_ref(Args &&... args)
Definition json.hpp:13799
json_ref(const value_type &value)
Definition json.hpp:13788
value_type const * operator->() const
Definition json.hpp:13824
json_ref(std::initializer_list< json_ref > init)
Definition json.hpp:13792
json_ref(value_type &&value)
Definition json.hpp:13784
value_type moved_or_copied() const
Definition json.hpp:13810
a template for a reverse iterator class
Definition json.hpp:12792
json_reverse_iterator(const typename base_iterator::iterator_type &it) noexcept
create reverse iterator from iterator
Definition json.hpp:12801
typename Base::reference reference
the reference type for the pointed-to element
Definition json.hpp:12798
json_reverse_iterator operator-(difference_type i) const
subtract from iterator
Definition json.hpp:12844
json_reverse_iterator & operator+=(difference_type i)
add to iterator
Definition json.hpp:12832
std::reverse_iterator< Base > base_iterator
shortcut to the reverse iterator adapter
Definition json.hpp:12796
json_reverse_iterator(const base_iterator &it) noexcept
create reverse iterator from base class
Definition json.hpp:12805
reference operator[](difference_type n) const
access to successor
Definition json.hpp:12856
json_reverse_iterator operator--(int) &
post-decrement (it–)
Definition json.hpp:12820
std::ptrdiff_t difference_type
Definition json.hpp:12794
difference_type operator-(const json_reverse_iterator &other) const
return difference
Definition json.hpp:12850
json_reverse_iterator operator+(difference_type i) const
add to iterator
Definition json.hpp:12838
json_reverse_iterator operator++(int) &
post-increment (it++)
Definition json.hpp:12808
auto key() const -> decltype(std::declval< Base >().key())
return the key of an object iterator
Definition json.hpp:12862
json_reverse_iterator & operator--()
pre-decrement (–it)
Definition json.hpp:12826
reference value() const
return the value of an iterator
Definition json.hpp:12869
json_reverse_iterator & operator++()
pre-increment (++it)
Definition json.hpp:12814
Definition json.hpp:6627
bool end_array()
Definition json.hpp:6690
bool start_object(std::size_t=static_cast< std::size_t >(-1))
Definition json.hpp:6670
typename BasicJsonType::string_t string_t
Definition json.hpp:6632
bool binary(binary_t &)
Definition json.hpp:6665
bool boolean(bool)
Definition json.hpp:6640
typename BasicJsonType::number_integer_t number_integer_t
Definition json.hpp:6629
typename BasicJsonType::number_float_t number_float_t
Definition json.hpp:6631
typename BasicJsonType::binary_t binary_t
Definition json.hpp:6633
bool key(string_t &)
Definition json.hpp:6675
bool end_object()
Definition json.hpp:6680
bool start_array(std::size_t=static_cast< std::size_t >(-1))
Definition json.hpp:6685
bool parse_error(std::size_t, const std::string &, const detail::exception &)
Definition json.hpp:6695
bool number_integer(number_integer_t)
Definition json.hpp:6645
bool string(string_t &)
Definition json.hpp:6660
bool number_unsigned(number_unsigned_t)
Definition json.hpp:6650
bool null()
Definition json.hpp:6635
typename BasicJsonType::number_unsigned_t number_unsigned_t
Definition json.hpp:6630
bool number_float(number_float_t, const string_t &)
Definition json.hpp:6655
typename BasicJsonType::string_t string_t
Definition json.hpp:6325
json_sax_dom_callback_parser & operator=(const json_sax_dom_callback_parser &)=delete
bool start_object(std::size_t len)
Definition json.hpp:6387
bool key(string_t &val)
Definition json.hpp:6405
constexpr bool is_errored() const
Definition json.hpp:6520
typename BasicJsonType::number_unsigned_t number_unsigned_t
Definition json.hpp:6323
typename BasicJsonType::number_integer_t number_integer_t
Definition json.hpp:6322
bool null()
Definition json.hpp:6345
typename BasicJsonType::parser_callback_t parser_callback_t
Definition json.hpp:6327
bool start_array(std::size_t len)
Definition json.hpp:6458
json_sax_dom_callback_parser(const json_sax_dom_callback_parser &)=delete
typename BasicJsonType::binary_t binary_t
Definition json.hpp:6326
bool binary(binary_t &val)
Definition json.hpp:6381
bool number_integer(number_integer_t val)
Definition json.hpp:6357
typename BasicJsonType::number_float_t number_float_t
Definition json.hpp:6324
bool end_array()
Definition json.hpp:6475
typename BasicJsonType::parse_event_t parse_event_t
Definition json.hpp:6328
bool boolean(bool val)
Definition json.hpp:6351
bool number_unsigned(number_unsigned_t val)
Definition json.hpp:6363
json_sax_dom_callback_parser & operator=(json_sax_dom_callback_parser &&)=default
bool string(string_t &val)
Definition json.hpp:6375
bool number_float(number_float_t val, const string_t &)
Definition json.hpp:6369
bool end_object()
Definition json.hpp:6422
json_sax_dom_callback_parser(json_sax_dom_callback_parser &&)=default
bool parse_error(std::size_t, const std::string &, const Exception &ex)
Definition json.hpp:6508
json_sax_dom_callback_parser(BasicJsonType &r, const parser_callback_t cb, const bool allow_exceptions_=true)
Definition json.hpp:6330
SAX implementation to create a JSON value from SAX events.
Definition json.hpp:6146
bool start_array(std::size_t len)
Definition json.hpp:6238
json_sax_dom_parser(const json_sax_dom_parser &)=delete
typename BasicJsonType::binary_t binary_t
Definition json.hpp:6152
json_sax_dom_parser & operator=(json_sax_dom_parser &&)=default
bool number_unsigned(number_unsigned_t val)
Definition json.hpp:6188
typename BasicJsonType::number_integer_t number_integer_t
Definition json.hpp:6148
bool boolean(bool val)
Definition json.hpp:6176
bool parse_error(std::size_t, const std::string &, const Exception &ex)
Definition json.hpp:6258
bool string(string_t &val)
Definition json.hpp:6200
bool end_object()
Definition json.hpp:6231
typename BasicJsonType::number_unsigned_t number_unsigned_t
Definition json.hpp:6149
bool start_object(std::size_t len)
Definition json.hpp:6212
bool null()
Definition json.hpp:6170
bool binary(binary_t &val)
Definition json.hpp:6206
constexpr bool is_errored() const
Definition json.hpp:6270
bool key(string_t &val)
Definition json.hpp:6224
json_sax_dom_parser(json_sax_dom_parser &&)=default
typename BasicJsonType::number_float_t number_float_t
Definition json.hpp:6150
json_sax_dom_parser & operator=(const json_sax_dom_parser &)=delete
bool number_float(number_float_t val, const string_t &)
Definition json.hpp:6194
bool end_array()
Definition json.hpp:6250
json_sax_dom_parser(BasicJsonType &r, const bool allow_exceptions_=true)
Definition json.hpp:6159
typename BasicJsonType::string_t string_t
Definition json.hpp:6151
bool number_integer(number_integer_t val)
Definition json.hpp:6182
Definition json.hpp:6734
JSON_HEDLEY_RETURNS_NON_NULL static JSON_HEDLEY_CONST const char * token_type_name(const token_type t) noexcept
return name of values of type token_type (only used for errors)
Definition json.hpp:6761
token_type
token types for the parser
Definition json.hpp:6738
@ value_float
an floating point number – use get_number_float() for actual value
@ begin_array
the character for array begin [
@ value_string
a string – use get_string() for actual value
@ end_array
the character for array end ]
@ uninitialized
indicating the scanner is uninitialized
@ parse_error
indicating a parse error
@ value_integer
a signed integer – use get_number_integer() for actual value
@ value_separator
the value separator ,
@ end_object
the character for object end }
@ begin_object
the character for object begin {
@ value_unsigned
an unsigned integer – use get_number_unsigned() for actual value
@ end_of_input
indicating the end of the input buffer
@ literal_or_value
a literal or the begin of a value (only for diagnostics)
lexical analysis
Definition json.hpp:6811
string_t & get_string()
return current string value (implicitly resets the token; useful only once)
Definition json.hpp:8129
token_type scan()
Definition json.hpp:8208
void skip_whitespace()
Definition json.hpp:8199
lexer & operator=(lexer &&)=default
bool skip_bom()
skip the UTF-8 byte order mark
Definition json.hpp:8185
lexer(InputAdapterType &&adapter, bool ignore_comments_=false) noexcept
Definition json.hpp:6822
constexpr position_t get_position() const noexcept
return position of last read token
Definition json.hpp:8139
constexpr number_integer_t get_number_integer() const noexcept
return integer value
Definition json.hpp:8111
typename lexer_base< BasicJsonType >::token_type token_type
Definition json.hpp:6820
lexer & operator=(lexer &)=delete
lexer(const lexer &)=delete
constexpr number_unsigned_t get_number_unsigned() const noexcept
return unsigned integer value
Definition json.hpp:8117
constexpr number_float_t get_number_float() const noexcept
return floating-point value
Definition json.hpp:8123
std::string get_token_string() const
Definition json.hpp:8147
lexer(lexer &&)=default
JSON_HEDLEY_RETURNS_NON_NULL constexpr const char * get_error_message() const noexcept
return syntax error message
Definition json.hpp:8172
exception indicating other library errors
Definition json.hpp:4070
static other_error create(int id_, const std::string &what_arg, BasicJsonContext context)
Definition json.hpp:4073
exception indicating access out of the defined range
Definition json.hpp:4053
static out_of_range create(int id_, const std::string &what_arg, BasicJsonContext context)
Definition json.hpp:4056
exception indicating a parse error
Definition json.hpp:3965
static parse_error create(int id_, const position_t &pos, const std::string &what_arg, BasicJsonContext context)
create a parse error exception
Definition json.hpp:3977
static parse_error create(int id_, std::size_t byte_, const std::string &what_arg, BasicJsonContext context)
Definition json.hpp:3985
const std::size_t byte
byte index of the parse error
Definition json.hpp:4002
Definition json.hpp:16984
const error_handler_t error_handler
error_handler how to react on decoding errors
Definition json.hpp:17916
const std::lconv * loc
the locale
Definition json.hpp:17901
std::array< char, 64 > number_buffer
a (hopefully) large enough character buffer
Definition json.hpp:17898
serializer(serializer &&)=delete
serializer & operator=(serializer &&)=delete
const char decimal_point
the locale's decimal point character
Definition json.hpp:17905
std::uint8_t state
Definition json.hpp:17326
std::size_t bytes
Definition json.hpp:17327
const char thousands_sep
the locale's thousand separator character
Definition json.hpp:17903
serializer & operator=(const serializer &)=delete
std::size_t undumped_chars
Definition json.hpp:17331
void dump(const BasicJsonType &val, const bool pretty_print, const bool ensure_ascii, const unsigned int indent_step, const unsigned int current_indent=0)
internal implementation of the serialization function
Definition json.hpp:17039
const char indent_char
the indentation character
Definition json.hpp:17911
std::size_t bytes_after_last_accept
Definition json.hpp:17330
std::array< char, 512 > string_buffer
string buffer
Definition json.hpp:17908
JSON_PRIVATE_UNLESS_TESTED const bool ensure_ascii
Definition json.hpp:17324
serializer(output_adapter_t< char > s, const char ichar, error_handler_t error_handler_=error_handler_t::strict)
Definition json.hpp:16999
serializer(const serializer &)=delete
string_t indent_string
the indentation string
Definition json.hpp:17913
exception indicating executing a member function with a wrong type
Definition json.hpp:4036
static type_error create(int id_, const std::string &what_arg, BasicJsonContext context)
Definition json.hpp:4039
JSON Pointer defines a string syntax for identifying a specific value within a JSON document.
Definition json.hpp:12911
friend json_pointer operator/(const json_pointer &lhs, string_t token)
create a new JSON pointer by appending the unescaped token at the end of the JSON pointer
Definition json.hpp:12995
void pop_back()
remove last reference token
Definition json.hpp:13023
friend json_pointer operator/(const json_pointer &lhs, std::size_t array_idx)
create a new JSON pointer by appending the array-index-token at the end of the JSON pointer
Definition json.hpp:13002
json_pointer parent_pointer() const
returns the parent of this JSON pointer
Definition json.hpp:13009
bool empty() const noexcept
return whether pointer points to the root document
Definition json.hpp:13061
json_pointer & operator/=(std::size_t array_idx)
append an array index at the end of this JSON pointer
Definition json.hpp:12980
void push_back(const string_t &token)
append an unescaped token at the end of the reference pointer
Definition json.hpp:13047
typename string_t_helper< RefStringType >::type string_t
Definition json.hpp:12933
json_pointer & operator/=(const json_pointer &ptr)
append another JSON pointer at the end of this JSON pointer
Definition json.hpp:12962
friend json_pointer operator/(const json_pointer &lhs, const json_pointer &rhs)
create a new JSON pointer by appending the right JSON pointer at the end of the left JSON pointer
Definition json.hpp:12987
friend class json_pointer
Definition json.hpp:12917
string_t to_string() const
return a string representation of the JSON pointer
Definition json.hpp:12943
friend bool operator==(json_pointer< RefStringTypeLhs > const &lhs, json_pointer< RefStringTypeRhs > const &rhs) noexcept
compares two JSON pointers for equality
Definition json.hpp:13751
const string_t & back() const
return last reference token
Definition json.hpp:13035
friend bool operator!=(json_pointer< RefStringTypeLhs > const &lhs, json_pointer< RefStringTypeRhs > const &rhs) noexcept
compares two JSON pointers for inequality
Definition json.hpp:13758
json_pointer & operator/=(string_t token)
append an unescaped reference token at the end of this JSON pointer
Definition json.hpp:12972
json_pointer(const string_t &s="")
create JSON pointer
Definition json.hpp:12937
void push_back(string_t &&token)
append an unescaped token at the end of the reference pointer
Definition json.hpp:13054
Definition parser.inl:1064
A TOML path.
Definition path.h:239
Base class for all library exceptions.
Definition exception.h:62
decltype(get< N >(std::declval< ::nlohmann::detail::iteration_proxy_value< IteratorType > >())) type
Definition json.hpp:4781
Definition toml.hpp:1295
constexpr bool is_array
Metafunction for determining if a type is, or is a reference to, a toml::array.
Definition forward_declarations.h:921
enum TOML_CLOSED_FLAGS_ENUM indentation
Combination mask of all indentation-enabling flags.
Definition forward_declarations.h:333
GLM_FUNC_DECL GLM_CONSTEXPR genType e()
Definition constants.inl:102
genType::value_type const * begin(genType const &v)
Definition range.hpp:70
#define NLOHMANN_BASIC_JSON_TPL_DECLARATION
Definition json.hpp:2508
#define JSON_HEDLEY_CONST
Definition json.hpp:1687
#define JSON_HEDLEY_DIAGNOSTIC_PUSH
Definition json.hpp:971
#define JSON_HEDLEY_WARN_UNUSED_RESULT
Definition json.hpp:1317
#define JSON_PRIVATE_UNLESS_TESTED
Definition json.hpp:2471
#define NLOHMANN_JSON_VERSION_PATCH
Definition json.hpp:52
#define JSON_HEDLEY_LIKELY(expr)
Definition json.hpp:1582
#define JSON_HEDLEY_NON_NULL(...)
Definition json.hpp:1475
#define JSON_INTERNAL_CATCH(exception)
Definition json.hpp:2438
#define JSON_HEDLEY_RETURNS_NON_NULL
Definition json.hpp:1916
#define JSON_CATCH(exception)
Definition json.hpp:2437
#define JSON_ASSERT(x)
Definition json.hpp:2464
#define JSON_THROW(exception)
Definition json.hpp:2435
#define NLOHMANN_JSON_VERSION_MAJOR
Definition json.hpp:50
#define NLOHMANN_BASIC_JSON_TPL
Definition json.hpp:2517
#define JSON_HEDLEY_UNLIKELY(expr)
Definition json.hpp:1583
#define JSON_TRY
Definition json.hpp:2436
#define JSON_NO_UNIQUE_ADDRESS
Definition json.hpp:2417
#define NLOHMANN_JSON_VERSION_MINOR
Definition json.hpp:51
#define NLOHMANN_CAN_CALL_STD_FUNC_IMPL(std_name)
Definition json.hpp:2692
#define JSON_HEDLEY_DIAGNOSTIC_POP
Definition json.hpp:972
#define JSON_EXPLICIT
Definition json.hpp:2729
#define JSON_HEDLEY_DEPRECATED_FOR(since, replacement)
Definition json.hpp:1265
#define JSON_HEDLEY_PURE
Definition json.hpp:1656
float position
Definition main.cpp:86
GeneratorWrapper< std::vector< T > > chunk(size_t size, GeneratorWrapper< T > &&generator)
Definition catch.hpp:4333
T const & operator+(T const &value, StreamEndStop)
Definition catch.hpp:538
auto operator+=(std::string &lhs, StringRef const &sr) -> std::string &
GLM_FUNC_DECL mat< 2, 2, T, Q > operator-(mat< 2, 2, T, Q > const &m)
Definition type_mat2x2.inl:355
GLM_FUNC_DECL mat< 2, 2, T, Q > operator*(mat< 2, 2, T, Q > const &m, T scalar)
Definition type_mat2x2.inl:413
Definition core_func_geometric.cpp:15
seed_t seed(text opt, text arg)
Definition lest.hpp:1214
detail namespace with internal helper functions
Definition json.hpp:109
typename std::enable_if< B, T >::type enable_if_t
Definition json.hpp:2862
typename T::reference reference_t
Definition json.hpp:3225
decltype(std::declval< StringType & >().append(std::declval< const Arg & >().data(), std::declval< const Arg & >().size())) string_can_append_data
Definition json.hpp:3781
bool operator<(const value_t lhs, const value_t rhs) noexcept
comparison operator for JSON types
Definition json.hpp:165
typename actual_object_comparator< BasicJsonType >::type actual_object_comparator_t
Definition json.hpp:3310
typename T::key_compare detect_key_compare
Definition json.hpp:3294
decltype(T::from_json(std::declval< Args >()...)) from_json_function
Definition json.hpp:3234
is_detected< string_can_append_iter, StringType, Arg > detect_string_can_append_iter
Definition json.hpp:3778
void to_json(BasicJsonType &j, T b) noexcept
Definition json.hpp:5047
value_type_t< iterator_traits< iterator_t< T > > > range_value_t
Definition json.hpp:3406
value_t
the JSON type enumeration
Definition json.hpp:139
@ number_integer
number value (signed integer)
@ discarded
discarded by the parser callback function
@ binary
binary array (ordered collection of bytes)
@ object
object (unordered set of name/value pairs)
@ number_float
number value (floating-point)
@ number_unsigned
number value (unsigned integer)
@ array
array (ordered collection of values)
make_index_sequence< sizeof...(Ts)> index_sequence_for
Definition json.hpp:2966
typename T::pointer pointer_t
Definition json.hpp:3222
is_detected< string_can_append, StringType, Arg > detect_string_can_append
Definition json.hpp:3766
typename T::difference_type difference_type_t
Definition json.hpp:3219
typename detector< nonesuch, void, Op, Args... >::type detected_t
Definition json.hpp:2294
integer_sequence< size_t, Ints... > index_sequence
Definition json.hpp:2904
typename std::conditional< is_key_type_comparable< BasicJsonType, KeyTypeCVRef >::value &&!(ExcludeObjectKeyType &&std::is_same< KeyType, typename BasicJsonType::object_t::key_type >::value) &&(!RequireTransparentComparator||is_detected< detect_is_transparent, typename BasicJsonType::object_comparator_t >::value) &&!is_json_iterator_of< BasicJsonType, KeyType >::value &&!is_json_pointer< KeyType >::value, std::true_type, std::false_type >::type is_usable_as_key_type
Definition json.hpp:3663
void to_json_tuple_impl(BasicJsonType &j, const Tuple &t, index_sequence< Idx... >)
Definition json.hpp:5170
enable_if_t< is_range< R >::value, result_of_begin< decltype(std::declval< R & >())> > iterator_t
Definition json.hpp:3403
std::is_convertible< detected_t< Op, Args... >, To > is_detected_convertible
Definition json.hpp:2307
typename std::remove_cv< typename std::remove_reference< T >::type >::type uncvref_t
Definition json.hpp:2848
decltype(std::declval< StringType & >().append(std::declval< Arg && >())) string_can_append
Definition json.hpp:3763
cbor_tag_handler_t
how to treat CBOR tags
Definition json.hpp:8501
@ store
store tags as binary type
@ error
throw a parse_error exception in case of a tag
error_handler_t
how to treat decoding errors
Definition json.hpp:16976
@ strict
throw a type_error exception in case of invalid UTF-8
@ ignore
ignore invalid UTF-8 sequences
@ replace
replace invalid UTF-8 sequences with U+FFFD
typename std::conditional< is_detected< detect_erase_with_key_type, typename BasicJsonType::object_t, KeyType >::value, std::true_type, std::false_type >::type has_erase_with_key_type
Definition json.hpp:3675
typename T::key_type key_type_t
Definition json.hpp:3213
StringType escape(StringType s)
string escaping as described in RFC 6901 (Sect. 4)
Definition json.hpp:2777
typename utility_internal::Gen< T, N >::type make_integer_sequence
Definition json.hpp:2950
std::is_same< Expected, detected_t< Op, Args... > > is_detected_exact
Definition json.hpp:2303
typename detected_or< Default, Op, Args... >::type detected_or_t
Definition json.hpp:2300
void concat_into(OutStringType &)
Definition json.hpp:3759
void replace_substring(StringType &s, const StringType &f, const StringType &t)
replace all occurrences of a substring by another string
Definition json.hpp:2758
typename detector< nonesuch, void, Op, Args... >::value_t is_detected
Definition json.hpp:2288
is_detected< string_can_append_data, StringType, Arg > detect_string_can_append_data
Definition json.hpp:3784
typename make_void< Ts... >::type void_t
Definition json.hpp:2250
OutStringType concat(Args &&... args)
Definition json.hpp:3843
make_integer_sequence< size_t, N > make_index_sequence
Definition json.hpp:2958
typename T::mapped_type mapped_type_t
Definition json.hpp:3210
decltype(std::declval< T >().template get< U >()) get_template_function
Definition json.hpp:3237
decltype(std::declval< ObjectType & >().erase(std::declval< KeyType >())) detect_erase_with_key_type
Definition json.hpp:3666
decltype(std::declval< StringType & >().append(std::declval< const Arg & >().begin(), std::declval< const Arg & >().end())) string_can_append_iter
Definition json.hpp:3775
typename T::is_transparent detect_is_transparent
Definition json.hpp:3643
typename is_comparable< typename BasicJsonType::object_comparator_t, const key_type_t< typename BasicJsonType::object_t > &, KeyType >::type is_key_type_comparable
Definition json.hpp:3640
typename T::iterator_category iterator_category_t
Definition json.hpp:3228
std::size_t concat_length()
Definition json.hpp:3728
is_detected< string_can_append_op, StringType, Arg > detect_string_can_append_op
Definition json.hpp:3772
decltype(std::declval< StringType & >()+=std::declval< Arg && >()) string_can_append_op
Definition json.hpp:3769
T conditional_static_cast(U value)
Definition json.hpp:3697
decltype(T::to_json(std::declval< Args >()...)) to_json_function
Definition json.hpp:3231
typename T::value_type value_type_t
Definition json.hpp:3216
namespace for Niels Lohmann
Definition json.hpp:107
basic_json<> json
default specialization
Definition json.hpp:3136
bool operator!=(json_pointer< RefStringTypeLhs > const &lhs, json_pointer< RefStringTypeRhs > const &rhs) noexcept
Definition json.hpp:13758
bool operator==(json_pointer< RefStringTypeLhs > const &lhs, json_pointer< RefStringTypeRhs > const &rhs) noexcept
Definition json.hpp:13751
Definition core_func_geometric.cpp:91
Definition tests.cpp:216
NLOHMANN_BASIC_JSON_TPL_DECLARATION void swap(nlohmann::NLOHMANN_BASIC_JSON_TPL &j1, nlohmann::NLOHMANN_BASIC_JSON_TPL &j2) noexcept(//NOLINT(readability-inconsistent-declaration-parameter-name) is_nothrow_move_constructible< nlohmann::NLOHMANN_BASIC_JSON_TPL >::value &&//NOLINT(misc-redundant-expression) is_nothrow_move_assignable< nlohmann::NLOHMANN_BASIC_JSON_TPL >::value)
exchanges the values of two JSON objects
Definition json.hpp:23140
__pstl::__internal::__enable_if_execution_policy< _ExecutionPolicy, _ForwardIterator > remove(_ExecutionPolicy &&__exec, _ForwardIterator __first, _ForwardIterator __last, const _Tp &__value)
Definition glue_algorithm_impl.h:484
__pstl::__internal::__enable_if_execution_policy< _ExecutionPolicy, _ForwardIterator2 > copy(_ExecutionPolicy &&__exec, _ForwardIterator1 __first, _ForwardIterator1 __last, _ForwardIterator2 __result)
Definition glue_algorithm_impl.h:248
__pstl::__internal::__enable_if_execution_policy< _ExecutionPolicy, void > reverse(_ExecutionPolicy &&__exec, _BidirectionalIterator __first, _BidirectionalIterator __last)
Definition glue_algorithm_impl.h:533
__pstl::__internal::__enable_if_execution_policy< _ExecutionPolicy, _ForwardIterator2 > transform(_ExecutionPolicy &&__exec, _ForwardIterator1 __first, _ForwardIterator1 __last, _ForwardIterator2 __result, _UnaryOperation __op)
Definition glue_algorithm_impl.h:318
__pstl::__internal::__enable_if_execution_policy< _ExecutionPolicy, void > fill(_ExecutionPolicy &&__exec, _ForwardIterator __first, _ForwardIterator __last, const _Tp &__value)
Definition glue_algorithm_impl.h:408
__pstl::__internal::__enable_if_execution_policy< _ExecutionPolicy, void > destroy(_ExecutionPolicy &&__exec, _ForwardIterator __first, _ForwardIterator __last)
Definition glue_memory_impl.h:224
__pstl::__internal::__enable_if_execution_policy< _ExecutionPolicy, bool > none_of(_ExecutionPolicy &&__exec, _ForwardIterator __first, _ForwardIterator __last, _Predicate __pred)
Definition glue_algorithm_impl.h:48
__pstl::__internal::__enable_if_execution_policy< _ExecutionPolicy, _ForwardIterator2 > move(_ExecutionPolicy &&__exec, _ForwardIterator1 __first, _ForwardIterator1 __last, _ForwardIterator2 __d_first)
Definition glue_algorithm_impl.h:752
__pstl::__internal::__enable_if_execution_policy< _ExecutionPolicy, _ForwardIterator > find(_ExecutionPolicy &&__exec, _ForwardIterator __first, _ForwardIterator __last, const _Tp &__value)
Definition glue_algorithm_impl.h:96
__pstl::__internal::__enable_if_execution_policy< _ExecutionPolicy, bool > all_of(_ExecutionPolicy &&__exec, _ForwardIterator __first, _ForwardIterator __last, _Predicate __pred)
__pstl::__internal::__enable_if_execution_policy< _ExecutionPolicy, _ForwardIterator1 > find_first_of(_ExecutionPolicy &&__exec, _ForwardIterator1 __first, _ForwardIterator1 __last, _ForwardIterator2 __s_first, _ForwardIterator2 __s_last, _BinaryPredicate __pred)
Definition glue_algorithm_impl.h:128
root
Definition version.py:42
TOML_NODISCARD TOML_EXPORTED_FREE_FUNCTION parse_result TOML_CALLCONV parse(std::string_view doc, std::string_view source_path={})
Parses a TOML document from a string view.
Definition toml.hpp:15819
default JSONSerializer template argument
Definition json.hpp:5220
static auto from_json(BasicJsonType &&j, TargetType &val) noexcept(noexcept(::nlohmann::from_json(std::forward< BasicJsonType >(j), val))) -> decltype(::nlohmann::from_json(std::forward< BasicJsonType >(j), val), void())
convert a JSON value to any value type
Definition json.hpp:5224
static auto from_json(BasicJsonType &&j) noexcept(noexcept(::nlohmann::from_json(std::forward< BasicJsonType >(j), detail::identity_tag< TargetType > {}))) -> decltype(::nlohmann::from_json(std::forward< BasicJsonType >(j), detail::identity_tag< TargetType > {}))
convert a JSON value to any value type
Definition json.hpp:5234
static auto to_json(BasicJsonType &j, TargetType &&val) noexcept(noexcept(::nlohmann::to_json(j, std::forward< TargetType >(val)))) -> decltype(::nlohmann::to_json(j, std::forward< TargetType >(val)), void())
convert any value type to a JSON value
Definition json.hpp:5244
typename BasicJsonType::default_object_comparator_t object_comparator_t
Definition json.hpp:3304
typename std::conditional< has_key_compare< object_t >::value, typename object_t::key_compare, object_comparator_t >::type type
Definition json.hpp:3306
typename BasicJsonType::object_t object_t
Definition json.hpp:3303
Definition json.hpp:3317
Definition json.hpp:2275
Default type
Definition json.hpp:2277
std::false_type value_t
Definition json.hpp:2276
static void construct(BasicJsonType &j, const CompatibleArrayType &arr)
Definition json.hpp:4959
static void construct(BasicJsonType &j, const std::valarray< T > &arr)
Definition json.hpp:4988
static void construct(BasicJsonType &j, const std::vector< bool > &arr)
Definition json.hpp:4972
static void construct(BasicJsonType &j, typename BasicJsonType::array_t &&arr)
Definition json.hpp:4947
static void construct(BasicJsonType &j, const typename BasicJsonType::array_t &arr)
Definition json.hpp:4937
static void construct(BasicJsonType &j, const typename BasicJsonType::binary_t &b)
Definition json.hpp:4876
static void construct(BasicJsonType &j, typename BasicJsonType::binary_t &&b)
Definition json.hpp:4885
static void construct(BasicJsonType &j, typename BasicJsonType::boolean_t b) noexcept
Definition json.hpp:4830
static void construct(BasicJsonType &j, typename BasicJsonType::number_float_t val) noexcept
Definition json.hpp:4898
static void construct(BasicJsonType &j, typename BasicJsonType::number_integer_t val) noexcept
Definition json.hpp:4924
static void construct(BasicJsonType &j, typename BasicJsonType::number_unsigned_t val) noexcept
Definition json.hpp:4911
static void construct(BasicJsonType &j, typename BasicJsonType::object_t &&obj)
Definition json.hpp:5017
static void construct(BasicJsonType &j, const typename BasicJsonType::object_t &obj)
Definition json.hpp:5007
static void construct(BasicJsonType &j, const CompatibleObjectType &obj)
Definition json.hpp:5028
static void construct(BasicJsonType &j, typename BasicJsonType::string_t &&s)
Definition json.hpp:4852
static void construct(BasicJsonType &j, const CompatibleStringType &str)
Definition json.hpp:4863
static void construct(BasicJsonType &j, const typename BasicJsonType::string_t &s)
Definition json.hpp:4843
typename BasicJsonType::template json_serializer< T, void > serializer
Definition json.hpp:3256
Definition json.hpp:3241
Definition json.hpp:3297
typename BasicJsonType::template json_serializer< T, void > serializer
Definition json.hpp:3271
typename BasicJsonType::template json_serializer< T, void > serializer
Definition json.hpp:3286
Definition json.hpp:3281
Definition json.hpp:2890
T value_type
Definition json.hpp:2891
static constexpr std::size_t size() noexcept
Definition json.hpp:2892
an iterator value
Definition json.hpp:11996
primitive_iterator_t primitive_iterator
generic iterator for all other types
Definition json.hpp:12002
BasicJsonType::array_t::iterator array_iterator
iterator for JSON arrays
Definition json.hpp:12000
BasicJsonType::object_t::iterator object_iterator
iterator for JSON objects
Definition json.hpp:11998
Definition json.hpp:3177
Definition json.hpp:3627
static constexpr auto value
Definition json.hpp:3478
Definition json.hpp:3597
Definition json.hpp:3413
static constexpr auto value
Definition json.hpp:3485
Definition json.hpp:3350
Definition json.hpp:2291
Definition json.hpp:3249
Definition json.hpp:3366
Definition json.hpp:3200
Definition json.hpp:3681
char one
Definition json.hpp:3682
@ value
Definition json.hpp:3692
static one test(decltype(&C::capacity))
Definition json.hpp:3385
static constexpr bool value
Definition json.hpp:3399
std::random_access_iterator_tag iterator_category
Definition json.hpp:3050
Definition json.hpp:3038
Definition json.hpp:3019
Definition json.hpp:2247
void type
Definition json.hpp:2248
Definition json.hpp:3324
Definition json.hpp:2261
nonesuch(nonesuch const &)=delete
void operator=(nonesuch &&)=delete
nonesuch(nonesuch const &&)=delete
void operator=(nonesuch const &)=delete
struct to capture the start position of the current token
Definition json.hpp:2812
std::size_t lines_read
the number of lines read
Definition json.hpp:2818
std::size_t chars_read_current_line
the number of characters read in the current line
Definition json.hpp:2816
std::size_t chars_read_total
the total number of characters read
Definition json.hpp:2814
Definition json.hpp:2973
Definition json.hpp:2979
static constexpr T value
Definition json.hpp:2980
Definition json.hpp:5190
auto operator()(BasicJsonType &j, T &&val) const noexcept(noexcept(to_json(j, std::forward< T >(val)))) -> decltype(to_json(j, std::forward< T >(val)), void())
Definition json.hpp:5192
typename Extend< typename Gen< T, N/2 >::type, N/2, N % 2 >::type type
Definition json.hpp:2931
a minimal map-like container that preserves insertion order
Definition json.hpp:17948
T & at(const Key &key)
Definition json.hpp:17995
std::vector< std::pair< const Key, T >, Allocator > Container
Definition json.hpp:17951
T mapped_type
Definition json.hpp:17950
const T & at(const Key &key) const
Definition json.hpp:18008
iterator find(const Key &key)
Definition json.hpp:18105
iterator erase(iterator pos)
Definition json.hpp:18040
void insert(InputIt first, InputIt last)
Definition json.hpp:18152
std::pair< iterator, bool > insert(value_type &&value)
Definition json.hpp:18129
const_iterator find(const Key &key) const
Definition json.hpp:18117
Key key_type
Definition json.hpp:17949
size_type erase(const Key &key)
Definition json.hpp:18021
T & operator[](const Key &key)
Definition json.hpp:17985
iterator erase(iterator first, iterator last)
Definition json.hpp:18045
typename Container::const_iterator const_iterator
Definition json.hpp:17953
typename std::enable_if< std::is_convertible< typename std::iterator_traits< InputIt >::iterator_category, std::input_iterator_tag >::value >::type require_input_iter
Definition json.hpp:18149
ordered_map(It first, It last, const Allocator &alloc=Allocator())
Definition json.hpp:17967
std::equal_to< Key > key_compare
Definition json.hpp:17959
ordered_map(const Allocator &alloc) noexcept(noexcept(Container(alloc)))
Definition json.hpp:17965
std::pair< iterator, bool > insert(const value_type &value)
Definition json.hpp:18134
typename Container::size_type size_type
Definition json.hpp:17954
typename Container::value_type value_type
Definition json.hpp:17955
ordered_map(std::initializer_list< value_type > init, const Allocator &alloc=Allocator())
Definition json.hpp:17969
ordered_map() noexcept(noexcept(Container()))
Definition json.hpp:17964
size_type count(const Key &key) const
Definition json.hpp:18093
typename Container::iterator iterator
Definition json.hpp:17952
std::pair< iterator, bool > emplace(const key_type &key, T &&t)
Definition json.hpp:17972
const T & operator[](const Key &key) const
Definition json.hpp:17990
std::size_t operator()(const nlohmann::NLOHMANN_BASIC_JSON_TPL &j) const
Definition json.hpp:23113
bool operator()(nlohmann::detail::value_t lhs, nlohmann::detail::value_t rhs) const noexcept
compare two value_t enum values
Definition json.hpp:23127